Compare commits

..
Author SHA1 Message Date
Jason K. Moore 599b513b8b Revert "kinematic_equation returns zero if speeds are zero" 2018-02-21 20:58:40 -08:00
1167 changed files with 61699 additions and 185904 deletions
-10
View File
@@ -1,10 +0,0 @@
This folder currently holds ``durations.json`` and ``blacklisted.json`` which are used in our pytest configuration.
``durations.json`` allows the two options ``--quickcheck`` and ``--veryquickcheck`` to be passed to ``pytest``.
Currently, the list of slow tests is updated intermittently by running::
$ ./.ci/generate_durations_log.sh
$ ./.ci/parse_durations_log.py
$ git commit -am "pytest: Updated .ci/durations.json"
make sure you have a C compiler, a Fortran compiler, numpy, scipy, cython, matplotlib & sage installed (the latter can
be tricky, in which case just make sure that no sage tests are removed in the git diff).
+195 -850
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -1,4 +1,4 @@
#!/bin/bash -e
#!/bin/bash
ABS_REPO_PATH=$(unset CDPATH && cd "$(dirname "$0")/.." && echo $PWD)
cat <<EOF >${ABS_REPO_PATH}/.ci/blacklisted.json
{
@@ -10,4 +10,4 @@ cat <<EOF >${ABS_REPO_PATH}/.ci/blacklisted.json
]
}
EOF
${PYTHON:-python} -m pytest -ra --durations 0 --verbose | tee $ABS_REPO_PATH/.ci/durations.log
python3 -m pytest -ra --durations 0 --verbose | tee $ABS_REPO_PATH/.ci/durations.log
-3
View File
@@ -1,3 +0,0 @@
# These are supported funding model platforms
custom: ['https://numfocus.salsalabs.org/donate-to-sympy/index.html']
+1 -10
View File
@@ -7,12 +7,9 @@
# track a file that is ignored for some reason, you have to use
# "git add -f". See "git help gitignore" for more information.
# Virtualenv
/.venv/
# Regular Python bytecode file
*.pyc
__pycache__/
# Optimized Python bytecode file
*.pyo
@@ -20,12 +17,6 @@ __pycache__/
# Vim's swap files
*.sw[op]
# VSCode settings file
.vscode/
# PyCharm settings file
/.idea/
# Generated files from Jython
*$py.class
@@ -79,7 +70,7 @@ sample.tex
.ipynb_checkpoints/
# pytest cache folder
.*cache
.cache
# pytest related data file for slow tests
.ci/durations.log
-36
View File
@@ -355,7 +355,6 @@ Peter Enenkel <peter.enenkel+git@gmail.com> <peter.enenkel+github@gmail.com>
Jithin D. George <jithindgeorge93@gmail.com>
Lev Chelyadinov <leva181777@gmail.com>
Sourav Ghosh <souravghosh2197@gmail.com>
Ethan Ward <etkewa@gmail.com> etkewa@gmail.com <qsRf9sGKy9rV>
Ethan Ward <etkewa@gmail.com>
Ethan Ward <etkewa@gmail.com> <ethanward@email.arizona.edu>
Nilabja Bhattacharya <nilabja10201992@gmail.com>
@@ -383,38 +382,3 @@ Ravi charan <ravicharan.vsp@gmail.com>
Nityananda Gohain <nityanandagohain@gmail.com>
Nicholas Bollweg <nick.bollweg@gmail.com> <nbollweg@continuum.io>
Johan Blåbäck <johan_bluecreek@riseup.net> <johan.blaback@cea.fr>
Adwait Baokar <adwaitbaokar18@gmail.com> abaokar-07 <adwaitbaokar18@gmail.com>
Rahil Hastu <rahilhastu@gmail.com> rahil hastu <rahilhastu@gmail.com>
Sidhant Nagpal <sidhantnagpal97@gmail.com> sidhantnagpal <sidhantnagpal97@gmail.com>
Sidhant Nagpal <sidhantnagpal97@gmail.com> “sidhantnagpal” <sidhantnagpal97@gmail.com>
Sidhant Nagpal <sidhantnagpal97@gmail.com> Sidhant Nagpal <36465988+sidhantnagpal@users.noreply.github.com>
Nikoleta Glynatsi <GlynatsiNE@cardiff.ac.uk> Nikoleta Glynatsi <glynatsine@cardiff.ac.uk>
Samyak Jain <samyak.jain2016a@vitstudent.ac.in> Samyak Jain <samtan106@gmail.com>
Avi Shrivastava <shrivastavaavi123@gmail.com> avi <shrivastavaavi123@gmail.com>
Gagandeep Singh <singh.23@iitj.ac.in> czgdp1807 <gdp.1807@gmail.com>
Gagandeep Singh <singh.23@iitj.ac.in> czgdp1807 <36567889+czgdp1807@users.noreply.github.com>
Gagandeep Singh <singh.23@iitj.ac.in> czgdp1807 <czgdp1807@gmail.com>
Gagandeep Singh <singh.23@iitj.ac.in> MathLover <36567889+czgdp1807@users.noreply.github.com>
Gagandeep Singh <singh.23@iitj.ac.in> czgdp1807 <singh.23@iitj.ac.in>
Gagandeep Singh <singh.23@iitj.ac.in> Gagandeep Singh <36567889+czgdp1807@users.noreply.github.com>
Gagandeep Singh <singh.23@iitj.ac.in> Gagandeep Singh <czgdp1807@gmail.com>
S.Y. Lee <sylee957@gmail.com> sylee957 <sylee957@gmail.com>
Yatna Verma <yatnavermaa@gmail.com> yatna <yatnavermaa@gmail.com>
Jared Lumpe <mjlumpe@gmail.com> Michael Jared Lumpe <mjlumpe@gmail.com>
Austin Palmer <ap4000@nyu.edu> austin <ap4000@nyu.edu>
Marduk Bolaños <mardukbp@mac.com> mardukbp <mardukbp@mac.com>
amsuhane <ayushsuhane99@iitkgp.ac.in> amsuhane <“ayushsuhane99@iitkgp.ac.in”>
Ritu Raj Singh <RituRajSingh878@gmail.com> Ritu Raj Singh <37741324+RituRajSingh878@users.noreply.github.com>
Ritu Raj Singh <RituRajSingh878@gmail.com> RituRajSingh878 <RituRajSingh878@gmail.com>
rationa-kunal <kunalgk1999@gmail.com> kunal <kunalgk1999@protonmail.com>
shiksha11 <shiksharawat01@gmail.com> shiksha11 <33157995+shiksha11@users.noreply.github.com>
Jogi Miglani <jmig5776@gmail.com> jmig5776 <jmig5776@gmail.com>
Supreet Agrawal <supreet11agrawal@gmail.com> stm <supreet11agrawal@gmail.com>
Bavish Kulur <bavishkulur@gmail.com> bavish2201 <bavishkulur@gmail.com>
Divyanshu Thakur <divyanshu@iiitmanipur.ac.in> Divyanshu <divyanshu@iiitmanipur.ac.in>
Shubham Kumar Jha <skjha832@gmail.com> ShubhamKJha <skjha832@gmail.com>
Frédéric Chapoton <fchapoton2@gmail.com> fchapoton <fchapoton2@gmail.com>
Salmista-94 <alejandrogroso@hotmail.com> alejandrogroso@hotmail.com <Salmista-94>
Jack <ivanenko@ucu.edu.ua> LilJohny <ivanenko@ucu.edu.ua>
Nabanita Dash <dashnabanita@gmail.com> Nabanita Dash <31562743+Naba7@users.noreply.github.com>
Rajiv Ranjan Singh <rajivperfect007@gmail.com> Rajiv Ranjan Singh <42106787+iamrajiv@users.noreply.github.com>
+135 -173
View File
@@ -1,69 +1,30 @@
language: python
sudo: false
stages:
- quality
- baseline
- test
env:
matrix:
- SPLIT="1/2" TEST_SYMPY="true"
- SPLIT="2/2" TEST_SYMPY="true"
- TEST_DOCTESTS="true" FASTCACHE="false" TEST_SETUP="true" TEST_EXAMPLES="true"
- TEST_DOCTESTS="true" FASTCACHE="false" TEST_SETUP="true"
- SPLIT="1/4" TEST_SYMPY="true"
- SPLIT="2/4" TEST_SYMPY="true"
- SPLIT="3/4" TEST_SYMPY="true"
- SPLIT="4/4" TEST_SYMPY="true"
global:
- secure: "YIEZal9EBTL+fg2YmoZoS8Bvt3eAVUOZjb38CtqpzR2CCSXWoUk35KG23m2NknlY1iKfYJyt7XWBszT/VKOQEbWQq7PIakV4vIByrWacgBxy1x3WC+rZoW7TX+JJiL+y942qIYbMoNMMB8xFpE5RDLSjSecMpFhJJXoafVTvju8="
dist: trusty
python:
- 2.7
- 3.4
- 3.5
- 3.6
matrix:
include:
- stage: quality
python: 3.7
dist: xenial
sudo: true
script: bin/test quality
env:
- stage: baseline
python: 3.7
dist: xenial
sudo: true
env:
- TEST_DOCTESTS="true" FASTCACHE="false" TEST_SETUP="true" TEST_EXAMPLES="true"
- python: 3.7
dist: xenial
sudo: true
env:
- SPLIT="1/2" TEST_SYMPY="true"
- python: 3.7
dist: xenial
sudo: true
env:
- SPLIT="2/2" TEST_SYMPY="true"
- stage: test
python: 3.8-dev
dist: xenial
sudo: true
env:
- TEST_DOCTESTS="true" FASTCACHE="false" TEST_SETUP="true" TEST_EXAMPLES="true"
- python: 3.8-dev
dist: xenial
sudo: true
env:
- SPLIT="1/2" TEST_SYMPY="true"
- python: 3.8-dev
dist: xenial
sudo: true
env:
- SPLIT="2/2" TEST_SYMPY="true"
- python: 2.7
env:
- TEST_ASCII="true"
# space separated list of optional dependencies(conda packages) to install and test
- TEST_OPT_DEPENDENCY="numpy scipy gmpy2 matplotlib>=2.2 theano llvmlite autowrap cython wurlitzer python-symengine=0.3.* tensorflow numexpr ipython antlr-python-runtime>=4.7,<4.8 antlr>=4.7,<4.8 cloudpickle python=2.7 pyglet pycosat python-clang"
# autowrap installs libgfortran libgcc gcc cython
- TEST_OPT_DEPENDENCY="numpy scipy gmpy2 matplotlib theano llvmlite autowrap python-symengine=0.3.* tensorflow numexpr ipython antlr-python-runtime>=4.7,<4.8 antlr>=4.7,<4.8"
addons:
apt:
packages:
@@ -73,13 +34,9 @@ matrix:
- liblapack-dev
- gfortran
- python: 3.6
# This is actually 3.7 (once all the dependencies support it). We use
# python: 3.6 here because 3.7 requires the slower xenial/sudo: true container,
# and we aren't actually using the Travis Python anyway.
env:
- TEST_ASCII="true"
- TEST_OPT_DEPENDENCY="numpy scipy gmpy2 matplotlib theano llvmlite autowrap cython wurlitzer python-symengine=0.3.* tensorflow numexpr ipython antlr-python-runtime>=4.7,<4.8 antlr>=4.7,<4.8 cloudpickle pyglet pycosat lfortran python-clang"
- TEST_SAGE="true"
- TEST_OPT_DEPENDENCY="numpy scipy gmpy2 matplotlib theano llvmlite autowrap python-symengine=0.3.* tensorflow numexpr ipython antlr-python-runtime>=4.7,<4.8 antlr>=4.7,<4.8"
addons:
apt:
packages:
@@ -90,9 +47,7 @@ matrix:
- gfortran
- python-scipy
- python: 3.7
dist: xenial
sudo: true
- python: 3.6
env:
- TEST_SPHINX="true"
- FASTCACHE="false"
@@ -114,97 +69,105 @@ matrix:
- python: 2.7
env:
- TEST_SLOW="true"
- SPLIT="1/2"
- SPLIT="1/3"
- python: 2.7
env:
- TEST_SLOW="true"
- SPLIT="2/2"
- python: 3.7
dist: xenial
sudo: true
- SPLIT="2/3"
- python: 2.7
env:
- TEST_SLOW="true"
- SPLIT="1/2"
- python: 3.7
dist: xenial
sudo: true
- SPLIT="3/3"
- python: 3.6
env:
- TEST_SLOW="true"
- SPLIT="2/2"
# Code coverage tests
- SPLIT="1/3"
- python: 3.6
dist: xenial
sudo: true
env:
- TEST_SYMPY="true"
- TEST_COVERAGE="true"
- SPLIT="1/4"
- TEST_SLOW="true"
- SPLIT="2/3"
- python: 3.6
dist: xenial
sudo: true
env:
- TEST_SYMPY="true"
- TEST_COVERAGE="true"
- SPLIT="2/4"
- python: 3.6
dist: xenial
sudo: true
env:
- TEST_SYMPY="true"
- TEST_COVERAGE="true"
- SPLIT="3/4"
- python: 3.6
dist: xenial
sudo: true
env:
- TEST_SYMPY="true"
- TEST_COVERAGE="true"
- SPLIT="4/4"
- TEST_SLOW="true"
- SPLIT="3/3"
# Everything here and below is in the allow_failures. The need to be
# duplicated here and in that section below.
- python: "pypy"
- python: 3.5 # Dummy value
env:
- TEST_DOCTESTS="true" TEST_EXAMPLES="true"
- TEST_SAGE="true"
- FASTCACHE="false"
addons:
apt:
sources:
- pypy
packages:
- pypy
- python: "pypy"
env:
- TEST_SYMPY="true"
- SPLIT="1/2"
- FASTCACHE="false"
addons:
apt:
sources:
- pypy
packages:
- pypy
- python: "pypy"
env:
- TEST_SYMPY="true"
- SPLIT="2/2"
- FASTCACHE="false"
addons:
apt:
sources:
- pypy
packages:
- pypy
sudo: true
fast_finish: true
- python: "pypy"
env:
- TEST_DOCTESTS="true"
- FASTCACHE="false"
- TEST_SETUP="true"
addons:
apt:
sources:
- pypy
packages:
- pypy
- python: "pypy"
env:
- TEST_SYMPY="true"
- SPLIT="1/4"
- FASTCACHE="false"
addons:
apt:
sources:
- pypy
packages:
- pypy
- python: "pypy"
env:
- TEST_SYMPY="true"
- SPLIT="2/4"
- FASTCACHE="false"
addons:
apt:
sources:
- pypy
packages:
- pypy
- python: "pypy"
env:
- TEST_SYMPY="true"
- SPLIT="3/4"
- FASTCACHE="false"
addons:
apt:
sources:
- pypy
packages:
- pypy
- python: "pypy"
env:
- TEST_SYMPY="true"
- SPLIT="4/4"
- FASTCACHE="false"
addons:
apt:
sources:
- pypy
packages:
- pypy
allow_failures:
# The apt installation of sage fails sometimes
- python: 3.5 # Dummy value
env:
- TEST_SAGE="true"
- FASTCACHE="false"
sudo: true
# PyPy randomly fails because of some PyPy bugs (Fatal RPython error: AssertionError)
- python: "pypy"
env:
- TEST_DOCTESTS="true"
- FASTCACHE="false"
- TEST_SETUP="true"
addons:
apt:
sources:
@@ -214,7 +177,7 @@ matrix:
- python: "pypy"
env:
- TEST_SYMPY="true"
- SPLIT="1/2"
- SPLIT="1/4"
- FASTCACHE="false"
addons:
apt:
@@ -225,7 +188,29 @@ matrix:
- python: "pypy"
env:
- TEST_SYMPY="true"
- SPLIT="2/2"
- SPLIT="2/4"
- FASTCACHE="false"
addons:
apt:
sources:
- pypy
packages:
- pypy
- python: "pypy"
env:
- TEST_SYMPY="true"
- SPLIT="3/4"
- FASTCACHE="false"
addons:
apt:
sources:
- pypy
packages:
- pypy
- python: "pypy"
env:
- TEST_SYMPY="true"
- SPLIT="4/4"
- FASTCACHE="false"
addons:
apt:
@@ -235,25 +220,19 @@ matrix:
- pypy
before_install:
- set -e
- python -c "import fcntl; fcntl.fcntl(1, fcntl.F_SETFL, 0)"
- if [[ "${FASTCACHE}" != "false" ]]; then
pip install fastcache;
fi
- if [[ "${TEST_COVERAGE}" == "true" ]]; then
pip install coverage;
coverage debug sys;
fi
- if [ "$TRAVIS_PYTHON_VERSION" == "3.8-dev" ]; then
pip uninstall -y Cython;
- if [[ "${TEST_SPHINX}" == "true" ]]; then
pip install "sphinx" "docutils" doctr;
fi
- |
if [[ -n "${TEST_OPT_DEPENDENCY}" ]]; then
if [[ "${TEST_OPT_DEPENDENCY}" ]]; then
# We do this conditionally because it saves us some downloading if the
# version is the same.
deactivate; # Deactivate the Travis virtualenv
if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then
wget https://repo.continuum.io/miniconda/Miniconda2-latest-Linux-x86_64.sh -q -O miniconda.sh;
wget https://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh -q -O miniconda.sh;
else
wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -q -O miniconda.sh;
fi
@@ -265,28 +244,19 @@ before_install:
conda config --prepend channels conda-forge --prepend channels symengine/label/dev;
conda info -a;
conda create -q -n test-environment ${TEST_OPT_DEPENDENCY};
conda create -q -n test-environment python=$TRAVIS_PYTHON_VERSION pip ${TEST_OPT_DEPENDENCY/autowrap/libgfortran libgcc gcc cython};
source activate test-environment;
export CPATH=$CONDA_PREFIX/include;
export LIBRARY_PATH=$CONDA_PREFIX/lib;
export LD_LIBRARY_PATH=$CONDA_PREFIX/lib;
export SYMPY_STRICT_COMPILER_CHECKS=1;
conda clean --all;
if [[ "$TEST_SAGE" == "true" ]]; then
# Use a separate environment because sage downgrades matplotlib
conda create -c conda-forge/label/cf201901 -n sage sagelib mpmath "ipython>=5.5.0,<6";
conda clean --all;
fi
if [[ "$TRAVIS_PYTHON_VERSION" == "3.6" ]]; then
conda install matchpy;
fi
elif [ "$TRAVIS_PYTHON_VERSION" != "pypy" ]; then
pip list | grep "numpy" && pip uninstall -y numpy;
pip list --format=legacy | grep "numpy" && pip uninstall -y numpy;
fi
- if [[ "${TEST_SPHINX}" == "true" ]]; then
pip install "sphinx" "docutils" doctr matplotlib sphinx-math-dollar;
- if [[ "${TEST_SAGE}" == "true" ]]; then
sudo apt-add-repository -y ppa:aims/sagemath;
sudo apt-get update;
sudo apt-get install -y sagemath-upstream-binary;
fi
- if [[ "$TRAVIS_PYTHON_VERSION" == "3.6" ]]; then
pip install matchpy;
fi
install:
# If a command fails, fail the build.
- set -e
@@ -294,27 +264,22 @@ install:
then virtualenv -p /usr/bin/pypy ~/.venv;
. ~/.venv/bin/activate;
fi
# Once https://github.com/fredrik-johansson/mpmath/pull/403 is in a released
# version of mpmath remove this line.
- pip install mpmath
# -We:invalid makes invalid escape sequences error in Python 3.6. See
# -#12028.
# SyntaxWarning flag for catching errors in Python3.8
# Issue - #16973. -We:invalid can be dropped from 3.8 onwards, but
# it needs to be there for earlier versions.
- |
if [[ "${TEST_SETUP}" == "true" ]]; then
# The install cycle below is to test installation on systems without
# setuptools.
virtualenv ~/.venv-no-setuptools;
~/.venv-no-setuptools/bin/pip install mpmath;
~/.venv-no-setuptools/bin/pip uninstall -y setuptools;
~/.venv-no-setuptools/bin/python -We:invalid setup.py -q install;
if [[ "${TEST_SAGE}" != "true" ]]; then
pip install mpmath;
if [[ "${TEST_SETUP}" == "true" ]]; then
# The install cycle below is to test installation on systems without setuptools.
pip uninstall -y setuptools;
python -We:invalid setup.py install;
pip uninstall -y sympy;
pip install --upgrade setuptools;
fi
python -We:invalid -m compileall -f sympy/;
python -We:invalid setup.py install;
pip list --format=columns;
fi
python -We:invalid -We::SyntaxWarning -m compileall -f -q sympy/;
python -We:invalid setup.py -q install;
pip list --format=columns;
script:
# Don't run doctr if the build fails
- set -e
@@ -322,8 +287,5 @@ script:
- if [[ "${TEST_SPHINX}" == "true" ]]; then
doctr deploy dev --deploy-repo sympy/sympy_doc --command './generate_indexes.py';
fi
- if [[ "${TEST_COVERAGE}" == "true" ]]; then
bash <(curl -s https://codecov.io/bash) || echo "Codecov did not collect coverage reports";
fi
notifications:
email: false
+1 -119
View File
@@ -4,7 +4,7 @@ those who explicitly didn't want to be mentioned. People with a * next
to their names are not found in the metadata of the git history. This
file is generated automatically by running `./bin/authors_update.py`.
There are a total of 822 authors.
There are a total of 704 authors.
Ondřej Čertík <ondrej@certik.cz>
Fabian Pedregosa <fabian@fseoane.net>
@@ -710,121 +710,3 @@ Nityananda Gohain <nityanandagohain@gmail.com>
Cédric Travelletti <cedrictravelletti@gmail.com>
Nicholas Bollweg <nick.bollweg@gmail.com>
Himanshu Ladia <hladia199811@gmail.com>
eward <eward@sunbelt-medical.com>
Adwait Baokar <adwaitbaokar18@gmail.com>
Mihail Tarigradschi <m.tarigradschi@gmail.com>
Saketh <alurusaisaketh@gmail.com>
rushyam <rushyamsonu@gmail.com>
sfoo <sfoohei@gmail.com>
Rahil Hastu <rahilhastu@gmail.com>
Zach Raines <raineszm@gmail.com>
Sidhant Nagpal <sidhantnagpal97@gmail.com>
Gagandeep Singh <singh.23@iitj.ac.in>
Rishav Chakraborty <annonymousxyz@outlook.com>
Malkhan Singh <malkhansinghrathaur@gmail.com>
Joaquim Monserrat <qmonserrat@mailoo.org>
Mayank Singh <mayank.singh081997@gmail.com>
Rémy Léone <rleone@online.net>
Maxence Mayrand <35958639+maxencemayrand@users.noreply.github.com>
Nikoleta Glynatsi <GlynatsiNE@cardiff.ac.uk>
helo9 <helo9@users.noreply.github.com>
Ken Wakita <wakita@is.titech.ac.jp>
Carl Sandrock <carl.sandrock@up.ac.za>
Fredrik Eriksson <freeriks@student.chalmers.se>
Ian Swire <oversizedpenguin@gmail.com>
Bulat <daianovich@mail.ru>
Ehren Metcalfe <ehren.m@gmail.com>
Dmitry Savransky <dsavransky@gmail.com>
Kiyohito Yamazaki <kyamaz@openql.org>
Caley Finn <caleyreuben@gmail.com>
zhouzq-thu <zzq_890709@hotmail.com>
Alexander Pozdneev <pozdneev@users.noreply.github.com>
Wes Turner <50891+westurner@users.noreply.github.com>
JMSS-Unknown <31131631+JMSS-Unknown@users.noreply.github.com>
Arshdeep Singh <singh.arshdeep1999@gmail.com>
cym1 <16437732+cym1@users.noreply.github.com>
Stewart Wadsworth <stewart.wadsworth@gmail.com>
Jared Lumpe <mjlumpe@gmail.com>
Avi Shrivastava <shrivastavaavi123@gmail.com>
ramvenkat98 <ramvenkat98@gmail.com>
Bilal Ahmed <b.ahmed0918@gmail.com>
Dimas Abreu Archanjo Dutra <dimasad@ufmg.br>
Yatna Verma <yatnavermaa@gmail.com>
S.Y. Lee <sylee957@gmail.com>
Miro Hrončok <miro@hroncok.cz>
Sudarshan Kamath <sudarshan.kamath97@gmail.com>
Ayushman Koul <ayushmankoul4570@gmail.com>
Robert Dougherty-Bliss <robert.w.bliss@gmail.com>
Andrey Grozin <A.G.Grozin@inp.nsk.su>
Bavish Kulur <bavishkulur@gmail.com>
Arun Singh <arunsin997@gmail.com>
sirnicolaf <43586954+sirnicolaf@users.noreply.github.com>
Zachariah Etienne <zachetie@gmail.com>
Prayush Dawda <35144226+iamprayush@users.noreply.github.com>
2torus <boris.ettinger@gmail.com>
Faisal Riyaz <faisalriyaz011@gmail.com>
Martin Roelfs <u0114255@kuleuven.be>
SirJohnFranklin <sirjfu@googlemail.com>
Anthony Sottile <asottile@umich.edu>
ViacheslavP <public.viacheslav@gmail.com>
Safiya03 <safiyanesar@gmail.com>
Alexander Dunlap <alexander.dunlap@gmail.com>
Rohit Sharma <31184621+rohitx007@users.noreply.github.com>
Jonathan Warner <warnerjon12@gmail.com>
Mohitbalwani26 <44258119+Mohitbalwani26@users.noreply.github.com>
Marduk Bolaños <mardukbp@mac.com>
amsuhane <ayushsuhane99@iitkgp.ac.in>
Matthias Geier <Matthias.Geier@gmail.com>
klaasvanaarsen <44929042+klaasvanaarsen@users.noreply.github.com>
Shubham Kumar Jha <skjha832@gmail.com>
rationa-kunal <kunalgk1999@gmail.com>
Animesh Sinha <animeshsinha1309@gmail.com>
Gaurang Tandon <1gaurangtandon@gmail.com>
Matthew Craven <clyring@users.noreply.github.com>
Daniel Ingram <ingramds@appstate.edu>
Jogi Miglani <jmig5776@gmail.com>
Takumasa Nakamura <n.takumasa@gmail.com>
Ritu Raj Singh <RituRajSingh878@gmail.com>
Rajiv Ranjan Singh <rajivperfect007@gmail.com>
Vera Lozhkina <veralozhkina@gmail.com>
adhoc-king <46354827+adhoc-king@users.noreply.github.com>
Mikel Rouco <mikel.mrm@gmail.com>
Oscar Gustafsson <oscar.gustafsson@gmail.com>
damianos <damianos@semmle.com>
Supreet Agrawal <supreet11agrawal@gmail.com>
shiksha11 <shiksharawat01@gmail.com>
Martin Ueding <dev@martin-ueding.de>
sharma-kunal <kunalsharma6914@gmail.com>
Divyanshu Thakur <divyanshu@iiitmanipur.ac.in>
Susumu Ishizuka <susumu.ishizuka@kii.com>
Samnan Rahee <namanush.rsr.16@gmail.com>
Fredrik Andersson <fredrik.andersson@fcc.chalmers.se>
Bhavya Srivastava <bhavya17037@iiitd.ac.in>
Alpesh Jamgade <alpeshjamgade21@gmail.com>
Shubham Abhang <shubhamabhang77@gmail.com>
Vishesh Mangla <manglavishesh64@gmail.com>
Nicko van Someren <nicko@nicko.org>
dandiez <47832466+dandiez@users.noreply.github.com>
Frédéric Chapoton <fchapoton2@gmail.com>
jhanwar <f2015463@pilani.bits-pilani.ac.in>
Noumbissi valere Gille Geovan <noumbissivalere@gmail.com>
Salmista-94 <alejandrogroso@hotmail.com>
Shivani Kohli <shivanikohli.09@gmail.com>
Parker Berry <parker.berry@marquette.edu>
Pragyan Mehrotra <pragyan18168@iiitd.ac.in>
Nabanita Dash <dashnabanita@gmail.com>
Gaetano Guerriero <x.guerriero@tin.it>
Ankit Pandey <pandeyan@grinnell.edu>
Ritesh Kumar <ritesh99rakesh@gmail.com>
kkkkx <709563092@qq.com>
wate123 <junlin0604@gmail.com>
Corwinpro <corwinat@gmail.com>
Anway De <anway1756@gmail.com>
znxftw <vishnu2101@gmail.com>
Jack <ivanenko@ucu.edu.ua>
OrestisVaggelis <orestis22000@gmail.com>
Nikhil Maan <nikhilmaan22@gmail.com>
Abhinav Anand <abhinav.anand2807@gmail.com>
sqs <googol.sqs@gmail.com>
Juan Barbosa <js.barbosa10@uniandes.edu.co>
Prionti Nasir <pdn3628@rit.edu>
+6 -6
View File
@@ -3,7 +3,7 @@
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to make participation in our project and
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
nationality, personal appearance, race, religion, or sexual identity and
@@ -48,13 +48,13 @@ threatening, offensive, or harmful.
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account or acting as an appointed
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing or otherwise unacceptable behavior may be
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting one of the project maintainers at asmeurer@gmail.com or
ondrej.certik@gmail.com. All complaints will be reviewed and investigated and
will result in a response that is deemed necessary and appropriate to the
@@ -69,7 +69,7 @@ members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at [https://contributor-covenant.org/version/1/4][version]
available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: https://contributor-covenant.org
[version]: https://contributor-covenant.org/version/1/4/
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/
+4 -4
View File
@@ -1,4 +1,4 @@
Copyright (c) 2006-2019 SymPy Development Team
Copyright (c) 2006-2018 SymPy Development Team
All rights reserved.
@@ -29,7 +29,7 @@ DAMAGE.
--------------------------------------------------------------------------------
Patches that were taken from the Diofant project (https://github.com/diofant/diofant)
Patches taken from the Diofant project (https://github.com/diofant/diofant)
are licensed as:
Copyright (c) 2006-2017 SymPy Development Team,
@@ -45,7 +45,7 @@ modification, are permitted provided that the following conditions are met:
b. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
c. Neither the name of Diofant or SymPy nor the names of its contributors
c. Neither the name of Diofant, or SymPy nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
@@ -64,7 +64,7 @@ DAMAGE.
--------------------------------------------------------------------------------
Submodules taken from the multipledispatch project (https://github.com/mrocklin/multipledispatch)
Submodule taken from the multipledispatch project (https://github.com/mrocklin/multipledispatch)
are licensed as:
Copyright (c) 2014 Matthew Rocklin
+1 -3
View File
@@ -5,11 +5,9 @@ recursive-include examples *.py README
include sympy/utilities/mathml/data/*.xsl
recursive-include sympy/parsing/latex *.g4 *.txt
recursive-include sympy/parsing/autolev *.g4 *.al
recursive-include sympy/parsing/latex *.g4 *.tokens *.interp *.txt
include LICENSE
include TODO
include AUTHORS
include README.rst
include bin/isympy
+1 -15
View File
@@ -4,24 +4,10 @@ was changed. Do not include the issue number in the title. -->
#### References to other Issues or PRs
<!-- If this pull request fixes an issue, write "Fixes #NNNN" in that exact
format, e.g. "Fixes #1234". See
https://github.com/blog/1506-closing-issues-via-pull-requests . Please also
write a comment on that issue linking back to this pull request once it is
open. -->
https://github.com/blog/1506-closing-issues-via-pull-requests .-->
#### Brief description of what is fixed or changed
#### Other comments
#### Release Notes
<!-- Write the release notes for this release below. See
https://github.com/sympy/sympy/wiki/Writing-Release-Notes for more information
on how to write release notes. The bot will check your release notes
automatically to see if they are formatted correctly. -->
<!-- BEGIN RELEASE NOTES -->
<!-- END RELEASE NOTES -->
+28 -22
View File
@@ -6,7 +6,7 @@ SymPy
.. |pypi version| image:: https://img.shields.io/pypi/v/sympy.svg
:target: https://pypi.python.org/pypi/sympy
.. |Build status| image:: https://secure.travis-ci.org/sympy/sympy.svg?branch=master
:target: https://travis-ci.org/sympy/sympy
:target: http://travis-ci.org/sympy/sympy
.. |Gitter Badge| image:: https://badges.gitter.im/Join%20Chat.svg
:alt: Join the chat at https://gitter.im/sympy/sympy
:target: https://gitter.im/sympy/sympy?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
@@ -15,7 +15,7 @@ SymPy
A Python library for symbolic mathematics.
https://sympy.org/
http://sympy.org/
See the AUTHORS file for the list of authors.
@@ -36,10 +36,7 @@ to ask us anything there. We have a very welcoming and helpful community.
Download
--------
The recommended installation method is through Anaconda,
https://www.anaconda.com/download/
You can also get the latest version of SymPy from
Get the latest version of SymPy from
https://pypi.python.org/pypi/sympy/
To get the git version do
@@ -49,14 +46,14 @@ To get the git version do
$ git clone git://github.com/sympy/sympy.git
For other options (tarballs, debs, etc.), see
https://docs.sympy.org/dev/install.html.
http://docs.sympy.org/dev/install.html.
Documentation and usage
-----------------------
Everything is at:
https://docs.sympy.org/
http://docs.sympy.org/
You can generate everything at the above site in your local copy of SymPy by::
@@ -82,7 +79,7 @@ To start it, issue::
$ bin/isympy
from this directory, if SymPy is not installed or simply::
from this directory if SymPy is not installed or simply::
$ isympy
@@ -91,7 +88,7 @@ if SymPy is installed.
Installation
------------
SymPy has a hard dependency on the `mpmath <http://mpmath.org/>`_
SymPy has a hard dependency on the `mpmath <http://mpmath.org/>`
library (version >= 0.19). You should install it first, please refer to
the mpmath installation guide:
@@ -105,7 +102,7 @@ If you install it system-wide, you may need to prefix the previous command with
$ sudo python setup.py install
See https://docs.sympy.org/dev/install.html for more information.
See http://docs.sympy.org/dev/install.html for more information.
Contributing
------------
@@ -138,8 +135,7 @@ To test pull requests, use `sympy-bot <https://github.com/sympy/sympy-bot>`_.
Regenerate Experimental `\LaTeX` Parser/Lexer
---------------------------------------------
The parser and lexer generated with the `ANTLR4 <http://antlr4.org>`_ toolchain
The parser and lexer generated with the `ANTLR4 <http://antlr4.org`_ toolchain
in `sympy/parsing/latex/_antlr` and checked into the repo. Presently, most
users should not need to regenerate these files, but if you plan to work on
this feature, you will need the `antlr4` command line tool available. One way
@@ -151,6 +147,16 @@ After making changes to `sympy/parsing/latex/LaTeX.g4`, run::
$ ./setup.py antlr
Usage in Python 3
-----------------
SymPy also supports Python 3. If you want to install the latest version in
Python 3, get the Python 3 tarball from
https://pypi.python.org/pypi/sympy/
To install the SymPy for Python 3, simply run the above commands with a Python
3 interpreter.
Clean
-----
@@ -188,11 +194,11 @@ Brief History
-------------
SymPy was started by Ondřej Čertík in 2005, he wrote some code during the
summer, then he wrote some more code during summer 2006. In February 2007,
summer, then he wrote some more code during the summer 2006. In February 2007,
Fabian Pedregosa joined the project and helped fixed many things, contributed
documentation and made it alive again. 5 students (Mateusz Paprocki, Brian
Jorgensen, Jason Gedge, Robert Schwarz, and Chris Wu) improved SymPy incredibly
during summer 2007 as part of the Google Summer of Code. Pearu Peterson
Jorgensen, Jason Gedge, Robert Schwarz and Chris Wu) improved SymPy incredibly
during the summer 2007 as part of the Google Summer of Code. Pearu Peterson
joined the development during the summer 2007 and he has made SymPy much more
competitive by rewriting the core from scratch, that has made it from 10x to
100x faster. Jurjen N.E. Bos has contributed pretty printing and other patches.
@@ -205,16 +211,16 @@ from Google Summer of Code students.
In 2011, Ondřej Čertík stepped down as lead developer, with Aaron Meurer, who
also started as a Google Summer of Code student, taking his place. Ondřej
Čertík is still active in the community but is too busy with work and family
Čertík is still active in the community, but is too busy with work and family
to play a lead development role.
Since then, a lot more people have joined the development and some people have
also left. You can see the full list in doc/src/aboutus.rst, or online at:
https://docs.sympy.org/dev/aboutus.html#sympy-development-team
http://docs.sympy.org/dev/aboutus.html#sympy-development-team
The git history goes back to 2007 when development moved from svn to hg. To
see the history before that point, look at https://github.com/sympy/sympy-old.
The git history goes back to 2007, when development moved from svn to hg. To
see the history before that point, look at http://github.com/sympy/sympy-old.
You can use git to see the biggest developers. The command::
@@ -244,12 +250,12 @@ A BibTeX entry for LaTeX users is
@article{10.7717/peerj-cs.103,
title = {SymPy: symbolic computing in Python},
author = {Meurer, Aaron and Smith, Christopher P. and Paprocki, Mateusz and \v{C}ert\'{i}k, Ond\v{r}ej and Kirpichev, Sergey B. and Rocklin, Matthew and Kumar, Amit and Ivanov, Sergiu and Moore, Jason K. and Singh, Sartaj and Rathnayake, Thilina and Vig, Sean and Granger, Brian E. and Muller, Richard P. and Bonazzi, Francesco and Gupta, Harsh and Vats, Shivam and Johansson, Fredrik and Pedregosa, Fabian and Curry, Matthew J. and Terrel, Andy R. and Rou\v{c}ka, \v{S}t\v{e}p\'{a}n and Saboo, Ashutosh and Fernando, Isuru and Kulal, Sumith and Cimrman, Robert and Scopatz, Anthony},
author = {Meurer, Aaron and Smith, Christopher P. and Paprocki, Mateusz and \v{C}ert\'{i}k, Ond\v{r}ej and Kirpichev, Sergey B. and Rocklin, Matthew and Kumar, AMiT and Ivanov, Sergiu and Moore, Jason K. and Singh, Sartaj and Rathnayake, Thilina and Vig, Sean and Granger, Brian E. and Muller, Richard P. and Bonazzi, Francesco and Gupta, Harsh and Vats, Shivam and Johansson, Fredrik and Pedregosa, Fabian and Curry, Matthew J. and Terrel, Andy R. and Rou\v{c}ka, \v{S}t\v{e}p\'{a}n and Saboo, Ashutosh and Fernando, Isuru and Kulal, Sumith and Cimrman, Robert and Scopatz, Anthony},
year = 2017,
month = jan,
keywords = {Python, Computer algebra system, Symbolics},
abstract = {
SymPy is an open source computer algebra system written in pure Python. It is built with a focus on extensibility and ease of use, through both interactive and programmatic applications. These characteristics have led SymPy to become a popular symbolic library for the scientific Python ecosystem. This paper presents the architecture of SymPy, a description of its features, and a discussion of select submodules. The supplementary material provides additional examples and further outline details of the architecture and features of SymPy.
SymPy is an open source computer algebra system written in pure Python. It is built with a focus on extensibility and ease of use, through both interactive and programmatic applications. These characteristics have led SymPy to become a popular symbolic library for the scientific Python ecosystem. This paper presents the architecture of SymPy, a description of its features, and a discussion of select submodules. The supplementary material provide additional examples and further outline details of the architecture and features of SymPy.
},
volume = 3,
pages = {e103},
+3 -7
View File
@@ -20,7 +20,7 @@ if sys.version_info < (3, 6):
from subprocess import run, PIPE
from distutils.version import LooseVersion
from collections import OrderedDict
from collections import defaultdict, OrderedDict
def red(text):
return "\033[31m%s\033[0m" % text
@@ -47,6 +47,8 @@ git_ver = run(['git', '--version'], stdout=PIPE, encoding='utf-8').stdout[12:]
if LooseVersion(git_ver) < LooseVersion(minimal):
print(yellow("Please use a git version >= %s" % minimal))
from sympy.utilities.misc import filldedent
def author_name(line):
assert line.count("<") == line.count(">") == 1
assert line.endswith(">")
@@ -90,10 +92,6 @@ try:
# this will fail if the .mailmap is not right
assert 'Sergey B Kirpichev' == author_name(git_people.pop(226)
), 'Sergey B Kirpichev was not found at line 226.'
assert 'azure-pipelines[bot]' == \
author_name(git_people.pop(751)), 'azure-pipelines[bot] was not found at line 751'
assert 'whitesource-bolt-for-github[bot]' == \
author_name(git_people.pop(792)), 'whitesource-bolt-for-github[bot] not found at line 792'
except AssertionError as msg:
print(red(msg))
sys.exit(1)
@@ -152,5 +150,3 @@ if new_authors:
print()
for i in sorted(new_authors, key=lambda x: x.lower()):
print('\t%s' % i)
else:
print(yellow("The AUTHORS file was updated."))
+19 -42
View File
@@ -30,9 +30,6 @@ except ImportError:
# It's html.parser in Python 3
from html.parser import HTMLParser
from sympy.utilities.misc import filldedent
# Load color templates, used from sympy/utilities/runtests.py
color_templates = (
("Black", "0;30"),
@@ -313,21 +310,14 @@ def process_function(name, c_name, b_obj, mod_path, f_sk, f_md, f_mdt, f_idt,
if name.startswith('_'):
f_sk.append(full_name)
else:
doc = obj.__doc__
if type(doc) is str:
if not doc:
add_md = True
elif not '>>>' in doc:
add_mdt = True
elif _is_indirect(name, doc):
add_idt = True
else:
f_doctest = True
elif doc is None:
# this was a function defined in the docstring
f_doctest = True
if not obj.__doc__:
add_md = True
elif not '>>>' in obj.__doc__:
add_mdt = True
elif _is_indirect(name, obj.__doc__):
add_idt = True
else:
assert None, type(doc)
f_doctest = True
function = True
@@ -380,23 +370,15 @@ def process_class(c_name, obj, c_sk, c_md, c_mdt, c_idt, c_has_doctest,
c = True
full_name = "LINE %d: %s" % (line_no, c_name)
doc = obj.__doc__
if type(doc) is str:
if not doc:
c_md.append(full_name)
elif not '>>>' in doc:
c_mdt.append(full_name)
elif _is_indirect(c_name, doc):
c_idt.append(full_name)
else:
c_dt = True
c_has_doctest.append(full_name)
elif doc is None:
# this was a class defined in the docstring
if not obj.__doc__:
c_md.append(full_name)
elif not '>>>' in obj.__doc__:
c_mdt.append(full_name)
elif _is_indirect(c_name, obj.__doc__):
c_idt.append(full_name)
else:
c_dt = True
c_has_doctest.append(full_name)
else:
assert None, type(doc)
in_sphinx = False
if sphinx:
@@ -453,7 +435,7 @@ def coverage(module_path, verbose=False, no_color=False, sphinx=True):
if member in skip_members:
continue
# Identify if the member (class/def) is a part of this module
# Identify if the member (class/def) a part of this module
obj = getattr(m, member)
obj_mod = inspect.getmodule(obj)
@@ -552,10 +534,6 @@ def coverage(module_path, verbose=False, no_color=False, sphinx=True):
def go(sympy_top, file, verbose=False, no_color=False, exact=True, sphinx=True):
# file names containing any string in skip_paths will be skipped,
skip_paths = []
if os.path.isdir(file):
doctests, total_sphinx, num_functions = 0, 0, 0
for F in os.listdir(file):
@@ -606,11 +584,10 @@ if __name__ == "__main__":
args = parser.parse_args()
if args.sphinx and not os.path.exists(os.path.join(sympy_top, 'doc', '_build', 'html')):
print(filldedent("""
Cannot check Sphinx coverage without a documentation build.
To build the docs, run "cd doc; make html". To skip
checking Sphinx coverage, pass --no-sphinx.
"""))
print("""
Cannot check Sphinx coverage without a documentation build. To build the
docs, run "cd doc; make html". To skip checking Sphinx coverage, pass --no-sphinx.
""")
sys.exit(1)
full_coverage = True
+38 -39
View File
@@ -27,7 +27,7 @@ from __future__ import print_function
import os
import re
import sys
from argparse import ArgumentParser
from optparse import OptionParser
minver = '3.4'
try:
@@ -37,10 +37,12 @@ try:
except ImportError:
print(
"You need to install module coverage (version %s or newer required).\n"
"See https://coverage.readthedocs.io/en/latest/ or \n"
"See http://nedbatchelder.com/code/coverage/ or \n"
"https://launchpad.net/ubuntu/+source/python-coverage/" % minver)
sys.exit(-1)
REPORT_DIR = "covhtml"
REFRESH = False
omit_dir_patterns = ['.*tests', 'benchmark', 'examples',
'pyglet', 'test_external']
@@ -58,13 +60,13 @@ def generate_covered_files(top_dir):
yield os.path.join(dirpath, filename)
def make_report(
test_args, source_dir='sympy/', report_dir='covhtml', use_cache=False,
slow=False
):
def make_report(source_dir, report_dir, use_cache=False, slow=False):
# code adapted from /bin/test
from get_sympy import path_hack
sympy_top = path_hack()
bin_dir = os.path.abspath(os.path.dirname(__file__)) # bin/
sympy_top = os.path.split(bin_dir)[0] # ../
sympy_dir = os.path.join(sympy_top, 'sympy') # ../sympy/
if os.path.isdir(sympy_dir):
sys.path.insert(0, sympy_top)
os.chdir(sympy_top)
cov = coverage.coverage()
@@ -77,43 +79,40 @@ def make_report(
cov.erase()
cov.start()
import sympy
sympy.test(*test_args, subprocess=False, slow=slow)
sympy.test(source_dir, subprocess=False)
if slow:
sympy.test(source_dir, subprocess=False, slow=slow)
#sympy.doctest() # coverage doesn't play well with doctests
cov.stop()
try:
cov.save()
except PermissionError:
import warnings
warnings.warn(
"PermissionError has been raised while saving the " \
"coverage result.",
RuntimeWarning
)
cov.save()
covered_files = list(generate_covered_files(source_dir))
if report_dir in os.listdir(os.curdir):
for f in os.listdir(report_dir):
if f.split('.')[-1] in ['html', 'css', 'js']:
os.remove(os.path.join(report_dir, f))
cov.html_report(morfs=covered_files, directory=report_dir)
parser = ArgumentParser()
parser.add_argument(
'-c', '--use-cache', action='store_true', default=False,
help='Use cached data.')
parser.add_argument(
'-d', '--report-dir', default='covhtml',
help='Directory to put the generated report in.')
parser.add_argument(
"--slow", action="store_true", dest="slow", default=False,
help="Run slow functions also.")
options, args = parser.parse_known_args()
if __name__ == '__main__':
report_dir = options.report_dir
use_cache = options.use_cache
slow = options.slow
make_report(
args, report_dir=report_dir, use_cache=use_cache, slow=slow)
parser = OptionParser()
parser.add_option('-c', '--use-cache', action='store_true', default=False,
help='Use cached data.')
parser.add_option('-d', '--report-dir', default='covhtml',
help='Directory to put the generated report in.')
parser.add_option("--slow", action="store_true", dest="slow",
default=False, help="Run slow functions also.")
options, args = parser.parse_args()
if args:
source_dir = args[0]
else:
source_dir = 'sympy/'
make_report(source_dir, **options.__dict__)
print("The generated coverage report is in covhtml directory.")
print(
"Open %s in your web browser to view the report" %
os.sep.join([report_dir, 'index.html'])
)
print("Open %s in your web browser to view the report" % os.sep.join(
'sympy covhtml index.html'.split()))
+1 -1
View File
@@ -4,7 +4,7 @@
Program to execute doctests using the py.test like interface.
The advantage over py.test is that it only depends on sympy and should just
work in any circumstances. See "sympy.doctest?" for documentation.
work in any circumstances. See "sympy.dotest?" for documentation.
"""
from __future__ import print_function
+1 -40
View File
@@ -1,4 +1,5 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
A tool to help keep .mailmap up-to-date with the
current git authors.
@@ -49,11 +50,6 @@ def author_name(line):
assert line.endswith(">")
return line.split("<", 1)[0].strip()
def author_email(line):
assert line.count("<") == line.count(">") == 1
assert line.endswith(">")
return line.split("<", 1)[1][:-1].strip()
sysexit = 0
print(blue("checking git authors..."))
@@ -120,41 +116,6 @@ if multi:
for e in sorted(dups[k]):
print('\t%s' % e)
bad_names = []
bad_emails = []
for i in git_people:
name = author_name(i)
email = author_email(i)
if '@' in name:
bad_names.append(i)
elif '@' not in email:
bad_emails.append(i)
if bad_names:
print()
print(yellow(filldedent("""
The following people appear to have an email address
listed for their name. Entries should be added to
.mailmap so that names are formatted like
"Name <email address>".
""")))
for i in bad_names:
print("\t%s" % i)
# TODO: Should we check for bad emails as well? Some people have empty email
# addresses. The above check seems to catch people who get the name and email
# backwards, so let's leave this alone for now.
# if bad_emails:
# print()
# print(yellow(filldedent("""
# The following names do not appear to have valid
# emails. Entries should be added to .mailmap that
# use a proper email address. If there is no email
# address for a person, use "none@example.com".
# """)))
# for i in bad_emails:
# print("\t%s" % i)
print()
print(blue("checking .mailmap..."))
+1 -2
View File
@@ -1,5 +1,4 @@
from __future__ import print_function
from sympy.core.compatibility import string_types
import time
import timeit
@@ -64,7 +63,7 @@ class TreeNode(object):
self.print_generic(n, method="exclusive_time")
def write_cachegrind(self, f):
if isinstance(f, string_types):
if isinstance(f, str):
f = open(f, "w")
f.write("events: Microseconds\n")
f.write("fl=sympyallimport\n")
-24
View File
@@ -1,24 +0,0 @@
#!/usr/bin/env python
"""
Test that only executable files have an executable bit set
"""
from __future__ import print_function
import os
import sys
from get_sympy import path_hack
base_dir = path_hack()
def test_executable(path):
if not os.path.isdir(path):
if os.access(path, os.X_OK):
with open(path, 'r') as f:
if f.readline()[:2] != "#!":
exn_msg = "File at " + path + " either should not be executable or should have a shebang line"
raise SystemError(exn_msg)
else:
for file in os.listdir(path):
test_executable(os.path.join(path, file))
test_executable(base_dir)
-88
View File
@@ -1,88 +0,0 @@
#!/usr/bin/env python
"""
Test that
from sympy import *
Doesn't import anything other than SymPy, it's hard dependencies (mpmath), and
hard optional dependencies (gmpy2, fastcache). Importing unnecessary libraries
can accidentally add hard dependencies to SymPy in the worst case, or at best
slow down the SymPy import time when they are installed.
Note, for this test to be effective, every external library that could
potentially be imported by SymPy must be installed.
TODO: Monkeypatch the importer to detect non-standard library imports even
when they aren't installed.
Based on code from
https://stackoverflow.com/questions/22195382/how-to-check-if-a-module-library-package-is-part-of-the-python-standard-library.
"""
# These libraries will always be imported with SymPy
hard_dependencies = ['mpmath']
# These libraries are optional, but are always imported at SymPy import time
# when they are installed. External libraries should only be added to this
# list if they are required for core SymPy functionality.
hard_optional_dependencies = ['gmpy', 'gmpy2', 'fastcache', 'pycosat']
import sys
import os
stdlib = {p for p in sys.path if p.startswith(sys.prefix) and
'site-packages' not in p}
existing_modules = list(sys.modules.keys())
# hook in-tree SymPy into Python path, if possible
this_path = os.path.abspath(__file__)
this_dir = os.path.dirname(this_path)
sympy_top = os.path.split(this_dir)[0]
sympy_dir = os.path.join(sympy_top, 'sympy')
if os.path.isdir(sympy_dir):
sys.path.insert(0, sympy_top)
def test_external_imports():
exec("from sympy import *", {})
bad = []
for mod in sys.modules:
if '.' in mod and mod.split('.')[0] in sys.modules:
# Only worry about the top-level modules
continue
if mod in existing_modules:
continue
if any(mod == i or mod.startswith(i + '.') for i in ['sympy'] +
hard_dependencies + hard_optional_dependencies):
continue
if mod in sys.builtin_module_names:
continue
fname = getattr(sys.modules[mod], "__file__", None)
if fname is None:
bad.append(mod)
continue
if fname.endswith(('__init__.py', '__init__.pyc', '__init__.pyo')):
fname = os.path.dirname(fname)
if os.path.dirname(fname) in stdlib:
continue
bad.append(mod)
if bad:
raise RuntimeError("""Unexpected external modules found when running 'from sympy import *':
""" + '\n '.join(bad))
print("No unexpected external modules were imported with 'from sympy import *'!")
if __name__ == '__main__':
test_external_imports()
+85 -146
View File
@@ -22,19 +22,9 @@ fi
if [[ "${TEST_SAGE}" == "true" ]]; then
echo "Testing SAGE"
source deactivate
source activate sage
sage -v
sage -python bin/test sympy/external/tests/test_sage.py
PYTHONPATH=. sage -t sympy/external/tests/test_sage.py
export MPMATH_NOSAGE=1
source deactivate
source activate test-environment
fi
if [[ -n "${TEST_OPT_DEPENDENCY}" ]]; then
python bin/test_external_imports.py
python bin/test_executable.py
sage -t sympy/external/tests/test_sage.py
fi
# We change directories to make sure that we test the installed version of
@@ -42,30 +32,9 @@ fi
mkdir empty
cd empty
if [[ "${TEST_COVERAGE}" == "true" ]]; then
rm -f $TRAVIS_BUILD_DIR/.coverage.* $TRAVIS_BUILD_DIR/.coverage
cat << EOF | python
import distutils.sysconfig
import os
with open(os.path.join(distutils.sysconfig.get_python_lib(), 'coverage.pth'), 'w') as pth:
pth.write('import sys; exec(%r)\n' % '''\
try:
import coverage
except ImportError:
pass
else:
coverage.process_startup()
''')
EOF
export COVERAGE_PROCESS_START=$TRAVIS_BUILD_DIR/coveragerc_travis
fi
if [[ "${TEST_ASCII}" == "true" ]]; then
# Force Python to act like pre-3.7 where LC_ALL=C causes
# UnicodeEncodeErrors. Once the lowest Python version we support is 3.7,
# we can consider dropping this test entirely. See PEP 538.
export PYTHONIOENCODING=ascii:strict
export OLD_LC_ALL=$LC_ALL
export LC_ALL=C
cat <<EOF | python
print('Testing ASCII')
try:
@@ -78,6 +47,7 @@ import sympy
if not (sympy.test('print') and sympy.doctest()):
raise Exception('Tests failed')
EOF
export LC_ALL=$OLD_LC_ALL
fi
if [[ "${TEST_DOCTESTS}" == "true" ]]; then
@@ -103,110 +73,58 @@ EOF
fi
# lambdify with tensorflow and numexpr is tested here
# TODO: Generate these tests automatically
if [[ -n "${TEST_OPT_DEPENDENCY}" ]]; then
if [[ "${TEST_OPT_DEPENDENCY}" == *"numpy"* ]]; then
cat << EOF | python
print('Testing optional dependencies')
print('Testing NUMPY')
import sympy
test_list = [
# numpy
'*numpy*',
'sympy/core/tests/test_numbers.py',
'sympy/matrices/',
'sympy/physics/quantum/',
'sympy/core/tests/test_sympify.py',
'sympy/utilities/tests/test_lambdify.py',
# scipy
'*scipy*',
# llvmlite
'*llvm*',
# theano
'*theano*',
# gmpy
'polys',
# autowrap
'*autowrap*',
# ipython
'*ipython*',
# antlr, lfortran, clang
'sympy/parsing/',
# matchpy
'*rubi*',
# codegen
'sympy/codegen/',
'sympy/utilities/tests/test_codegen',
'sympy/utilities/_compilation/tests/test_compilation',
# cloudpickle
'pickling',
# pycosat
'sympy/logic',
'sympy/assumptions',
]
blacklist = [
'sympy/physics/quantum/tests/test_circuitplot.py',
]
doctest_list = [
# numpy
'sympy/matrices/',
'sympy/utilities/lambdify.py',
# scipy
'*scipy*',
# llvmlite
'*llvm*',
# theano
'*theano*',
# gmpy
'polys',
# autowrap
'*autowrap*',
# ipython
'*ipython*',
# antlr, lfortran, clang
'sympy/parsing/',
# matchpy
'*rubi*',
# codegen
'sympy/codegen/',
# pycosat
'sympy/logic',
'sympy/assumptions',
]
if not (sympy.test(*test_list, blacklist=blacklist) and sympy.doctest(*doctest_list)):
if not (sympy.test('*numpy*', 'sympy/core/tests/test_numbers.py',
'sympy/matrices/', 'sympy/physics/quantum/',
'sympy/core/tests/test_sympify.py',
'sympy/utilities/tests/test_lambdify.py',
blacklist=['sympy/physics/quantum/tests/test_circuitplot.py'])
and sympy.doctest('sympy/matrices/', 'sympy/utilities/lambdify.py')):
raise Exception('Tests failed')
EOF
fi
if [[ "${TEST_OPT_DEPENDENCY}" == *"scipy"* ]]; then
cat << EOF | python
print('Testing SCIPY')
import sympy
# scipy matrices are tested in numpy testing
if not sympy.test('sympy/external/tests/test_scipy.py'):
raise Exception('Tests failed')
EOF
fi
if [[ "${TEST_OPT_DEPENDENCY}" == *"llvmlite"* ]]; then
cat << EOF | python
print('Testing LLVMJIT')
import sympy
if not (sympy.test('sympy/printing/tests/test_llvmjit.py')
and sympy.doctest('sympy/printing/llvmjitcode.py')):
raise Exception('Tests failed')
EOF
fi
if [[ "${TEST_OPT_DEPENDENCY}" == *"theano"* ]]; then
cat << EOF | python
print('Testing THEANO')
import sympy
if not sympy.test('*theano*'):
raise Exception('Tests failed')
EOF
fi
if [[ "${TEST_OPT_DEPENDENCY}" == *"gmpy"* ]]; then
cat << EOF | python
print('Testing GMPY')
import sympy
if not (sympy.test('sympy/polys/') and sympy.doctest('sympy/polys/')):
raise Exception('Tests failed')
EOF
cd ..
bin/doctest doc/src/modules/numeric-computation.rst
fi
# This is separate because it needs to be run with subprocess=False
if [[ "${TEST_OPT_DEPENDENCY}" == *"matplotlib"* ]]; then
cat << EOF | python
print('Testing MATPLOTLIB')
@@ -224,6 +142,37 @@ if not (sympy.test('sympy/plotting', 'sympy/physics/quantum/tests/test_circuitpl
EOF
fi
if [[ "${TEST_OPT_DEPENDENCY}" == *"autowrap"* ]]; then
cat << EOF | python
print('Testing AUTOWRAP')
import sympy
if not (sympy.test('sympy/external/tests/test_autowrap.py')
and sympy.doctest('sympy/utilities/autowrap.py')):
raise Exception('Tests failed')
EOF
fi
if [[ "${TEST_OPT_DEPENDENCY}" == *"ipython"* ]]; then
cat << EOF | python
print('Testing IPYTHON')
import sympy
if not sympy.test('*ipython*'):
raise Exception('Tests failed')
EOF
fi
if [[ "${TEST_SYMPY}" == "true" ]]; then
# -We:invalid makes invalid escape sequences error in Python 3.6. See
# -#12028.
cat << EOF | python -We:invalid
print('Testing SYMPY, split ${SPLIT}')
import sympy
if not sympy.test(split='${SPLIT}'):
raise Exception('Tests failed')
EOF
fi
if [[ "${TEST_OPT_DEPENDENCY}" == *"symengine"* ]]; then
export USE_SYMENGINE=1
cat << EOF | python
@@ -237,21 +186,11 @@ EOF
unset USE_SYMENGINE
fi
if [[ "${TEST_SYMPY}" == "true" ]]; then
# -We:invalid makes invalid escape sequences error in Python 3.6. See
# -#12028.
if [[ "${TEST_OPT_DEPENDENCY}" == *"antlr"* ]]; then
cat << EOF | python -We:invalid
print('Testing SYMPY, split ${SPLIT}')
print('Testing ANTLR')
import sympy
if not sympy.test(split='${SPLIT}'):
raise Exception('Tests failed')
if not sympy.test('sympy/parsing/tests/test_latex'):
raise Exception('Tests failed')
EOF
fi
if [[ "${TEST_COVERAGE}" == "true" ]]; then
unset COVERAGE_PROCESS_START
fi
if [[ "${TEST_EXAMPLES}" == "true" ]]; then
# No need to change directory if executed after the rst doctest
examples/all.py -q
fi
-15
View File
@@ -1,15 +0,0 @@
coverage:
status:
project:
default:
target: 0%
threshold: 100%
patch: false
precision: 3
comment:
layout: "diff"
behavior: default
require_changes: true
-14
View File
@@ -8,24 +8,10 @@ import json
import sys
import warnings
import pytest
from sympy.utilities.runtests import setup_pprint, _get_doctest_blacklist
durations_path = os.path.join(os.path.dirname(__file__), '.ci', 'durations.json')
blacklist_path = os.path.join(os.path.dirname(__file__), '.ci', 'blacklisted.json')
# Collecting tests from rubi_tests under pytest leads to errors even if the
# tests will be skipped.
collect_ignore = ["sympy/integrals/rubi"] + _get_doctest_blacklist()
if sys.version_info < (3,):
collect_ignore.append('doc/src/gotchas.rst')
# Set up printing for doctests
setup_pprint()
sys.__displayhook__ = sys.displayhook
#from sympy import pprint_use_unicode
#pprint_use_unicode(False)
def _mk_group(group_dict):
return list(chain(*[[k+'::'+v for v in files] for k, files in group_dict.items()]))
-17
View File
@@ -1,17 +0,0 @@
[run]
parallel = True
branch = True
source = sympy
omit =
*/tests/*
*/benchmarks/*
*/sympy/integrals/rubi/rules/*
*/sympy/plotting/pygletplot/*
*/conftest.py
data_file = $TRAVIS_BUILD_DIR/.coverage
[report]
exclude_lines =
\#.*pragma:\s*no.?cover
^\s*if SYMPY_DEBUG:
show_missing = True
+3 -3
View File
@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/python
#
# TeXmacs interface for SymPy
#
@@ -11,7 +11,7 @@
# heuristics to know where a multi-line expression is
# broken. As a result you can't use more than one space
# in a sequence. However you can and must indent your
# expression using standard Python rules.
# expression using standard Pyhon rules.
#
# You can retrieve the last output using '_' built-in
# symbol. If the previous command did not generate
@@ -65,7 +65,7 @@ f = Function('f')
Gamma, Zeta = gamma, zeta
_greek = 'alpha beta gamma delta epsilon zeta eta ' \
'theta iota kappa mu nu xi omicron rho ' \
'theta iota kappa mu nu xi omicron pi rho ' \
'sigma tau upsilon phi chi psi omega'
for _symbol in _greek.split(' '):
View File
+3 -69
View File
@@ -6,32 +6,22 @@ Debian/Ubuntu
To make the html documentation, install the prerequisites::
apt-get install python-sphinx texlive-latex-recommended dvipng librsvg2-bin imagemagick docbook2x graphviz
python -m pip install sphinx-math-dollar
apt-get install python-sphinx texlive-latex-recommended dvipng librsvg2-bin imagemagick docbook2x
and do::
make html
If you get **mpmath** error, install python-mpmath package::
apt-get install python-mpmath
If you get **matplotlib** error, install python-matplotlib package::
apt-get install python-matplotlib
and to view it, do::
firefox _build/html/index.html
epiphany _build/html/index.html
Fedora
------
Fedora (and maybe other RPM based distributions), install the prerequisites::
dnf install python3-sphinx librsvg2 ImageMagick docbook2X texlive-dvipng-bin texlive-scheme-medium librsvg2-tools
python -m pip install sphinx-math-dollar
dnf install python3-sphinx librsvg2 ImageMagick docbook2X texlive-dvipng-bin texlive-scheme-medium librsvg2-tools
After that, run::
@@ -41,62 +31,6 @@ If you get **mpmath** error, install python3-mpmath package::
dnf install python3-mpmath
If you get **matplotlib** error, install python3-matplotlib package::
dnf install python3-matplotlib
And view it at::
_build/html/index.html
Mac
---
- Install MacTex: http://www.tug.org/mactex/
- Install homebrew: https://brew.sh/
Install these packages with homebrew:
```bash
brew install imagemagick graphviz docbook librsvg
```
Install these packages with either pip or conda:
```bash
python -m pip install mpmath matplotlib sphinx sphinx-math-dollar
```
or
```bash
conda install -c conda-forge mpmpath matplotlib sphinx sphinx-math-dollar
```
Windows 10
----------
Making your sphinx build successful on the Windows system is tricky because of
some dependencies like dvipng or docbook2x not available.
For Windows 10, however, the Windows Subsystem for Linux can be a possible
workaround solution, and you can install Ubuntu shell on your Windows system
after following up the tutorial below
https://github.com/MicrosoftDocs/WSL/blob/live/WSL/install-win10.md
In your command prompt, simply run 'ubuntu' to transfer to linux terminal,
and follow up the Debian/Ubuntu tutorial above to install all the dependencies,
and then you can run 'make html' to build.
(Note that you would also have to install 'make' via 'apt-get install make')
If you want to change directory in your prompt to your working folder of sympy
in windows file system, you can prepend 'cd /mnt/' to your file path in windows,
and run in your shell to navigate to the folder.
(Also note that linux uses '/' instead of '\\' for path)
This method would provide better compatibility than cygwin or msys2,
and more convenience than a virtual machine, if you partially need linux
environment for your workflow.
However this method is only viable for Windows 10 64-bit users.
+1 -1
View File
@@ -1,7 +1,7 @@
[epydoc]
name : SymPy
url: https://code.google.com/p/sympy
url: http://code.google.com/p/sympy
modules : sympy, sympy.core, sympy.modules
+1 -1
View File
@@ -16,7 +16,7 @@
\usetikzlibrary{shapes,snakes}
\usepackage{amsmath,amssymb}
\begin{document}
\begin{center}\huge{\textbf{SymPy Cheatsheet (https://sympy.org)}}\end{center}
\begin{center}\huge{\textbf{SymPy Cheatsheet (http://sympy.org)}}\end{center}
\begin{multicols*}{3}
+3 -3
View File
@@ -425,7 +425,7 @@ Test if permutation \verb!g! belong to self.
\verb!coset_factor(g, af=False)!\\
Return G's (self's) coset factorization, \verb!f,! of \verb!g!.
Return GÔs (selfÕs) coset factorization, \verb!f,! of \verb!g!.
@@ -458,7 +458,7 @@ Return iterator to generate the elements of the group
\verb!generate_dimino(af=False)!\\
Yield group elements using Dimino's algorithm
Yield group elements using DiminoÕs algorithm
\verb!generate_schreier_sims(af=False)!\\
@@ -1014,7 +1014,7 @@ Verify the centralizer of a group/set/element inside another group.
\rule{0.3\linewidth}{0.25pt}
\scriptsize\\
https://www.sympy.org/cheatsheets
http://www.sympy.org/cheatsheets
\end{multicols}
+38 -12
View File
@@ -7,10 +7,7 @@ import inspect
import textwrap
import re
import pydoc
try:
from collections.abc import Mapping
except ImportError: # Python 2
from collections import Mapping
import collections
import sys
@@ -90,7 +87,7 @@ class Reader(object):
return not ''.join(self._str).strip()
class NumpyDocString(Mapping):
class NumpyDocString(collections.Mapping):
def __init__(self, docstring, config={}):
docstring = textwrap.dedent(docstring).split('\n')
@@ -108,10 +105,10 @@ class NumpyDocString(Mapping):
'Attributes': [],
'Methods': [],
'See Also': [],
# 'Notes': [],
'Notes': [],
'Warnings': [],
'References': '',
# 'Examples': '',
'Examples': '',
'index': {}
}
self._other_keys = []
@@ -538,17 +535,18 @@ class ClassDoc(NumpyDocString):
if not self[field]:
doc_list = []
for name in sorted(items):
clsname = getattr(self._cls, name, None)
if clsname is not None:
doc_item = pydoc.getdoc(clsname)
try:
doc_item = pydoc.getdoc(getattr(self._cls, name))
doc_list.append((name, '', splitlines_x(doc_item)))
except AttributeError:
pass # method doesn't exist
self[field] = doc_list
@property
def methods(self):
if self._cls is None:
return []
return [name for name, func in inspect.getmembers(self._cls)
return [name for name, func in inspect_getmembers(self._cls)
if ((not name.startswith('_')
or name in self.extra_public_methods)
and callable(func))]
@@ -557,5 +555,33 @@ class ClassDoc(NumpyDocString):
def properties(self):
if self._cls is None:
return []
return [name for name, func in inspect.getmembers(self._cls)
return [name for name, func in inspect_getmembers(self._cls)
if not name.startswith('_') and func is None]
# This function was taken verbatim from Python 2.7 inspect.getmembers() from
# the standard library. The difference from Python < 2.7 is that there is the
# try/except AttributeError clause added, which catches exceptions like this
# one: https://gist.github.com/1471949
def inspect_getmembers(object, predicate=None):
"""
Return all members of an object as (name, value) pairs sorted by name.
Optionally, only return members that satisfy a given predicate.
"""
results = []
for key in dir(object):
try:
value = getattr(object, key)
except AttributeError:
continue
if not predicate or predicate(value):
results.append((key, value))
results.sort()
return results
def _is_show_member(self, name):
if self.show_inherited_members:
return True # show all class members
if name not in self._cls.__dict__:
return False # class member is inherited, we do not show it
return True
+5 -4
View File
@@ -1,5 +1,4 @@
from __future__ import division, absolute_import, print_function
from sympy.core.compatibility import string_types
import sys
import re
@@ -195,7 +194,7 @@ class SphinxDocString(NumpyDocString):
out = []
if self['References']:
out += self._str_header('References')
if isinstance(self['References'], string_types):
if isinstance(self['References'], str):
self['References'] = [self['References']]
out.extend(self['References'])
out += ['']
@@ -239,10 +238,12 @@ class SphinxDocString(NumpyDocString):
for param_list in ('Other Parameters', 'Raises', 'Warns'):
out += self._str_param_list(param_list)
out += self._str_warnings()
out += self._str_see_also(func_role)
out += self._str_section('Notes')
out += self._str_references()
out += self._str_examples()
for s in self._other_keys:
out += self._str_section(s)
out += self._str_see_also(func_role)
out += self._str_references()
out += self._str_member_list('Attributes')
out = self._str_indent(out, indent)
return '\n'.join(out)
+2 -5
View File
@@ -23,10 +23,7 @@ import re
import pydoc
import sphinx
import inspect
try:
from collections.abc import Callable
except ImportError: # Python 2
from collections import Callable
import collections
if sphinx.__version__ < '1.0.1':
raise RuntimeError("Sphinx 1.0.1 or newer is required")
@@ -104,7 +101,7 @@ def mangle_signature(app, what, name, obj, options, sig, retann):
'initializes x; see ' in pydoc.getdoc(obj.__init__))):
return '', ''
if not (isinstance(obj, Callable) or
if not (isinstance(obj, collections.Callable) or
hasattr(obj, '__argspec_is_invalid_')):
return
+2 -2
View File
@@ -2,7 +2,7 @@
sympylive
~~~~~~~~~
Allow `SymPy Live <https://live.sympy.org/>`_ to be used for interactive
Allow `SymPy Live <http://live.sympy.org/>`_ to be used for interactive
evaluation of SymPy's code examples.
:copyright: Copyright 2014 by the SymPy Development Team, see AUTHORS.
@@ -30,5 +30,5 @@ def builder_inited(app):
def setup(app):
app.add_config_value('sympylive_url', 'https://live.sympy.org', False)
app.add_config_value('sympylive_url', 'http://live.sympy.org', False)
app.connect('builder-inited', builder_inited)
+32 -44
View File
@@ -4,12 +4,11 @@
This script creates logos of different formats from the source "sympy.svg"
Requirements:
rsvg-convert - for converting to *.png format
(librsvg2-bin deb package)
rsvg-convert - for converting to *.png format (librsvg2-bin deb package)
imagemagick - for converting to *.ico favicon format
"""
from argparse import ArgumentParser
from optparse import OptionParser
import xml.dom.minidom
import os.path
import logging
@@ -23,69 +22,61 @@ default_output_dir = os.path.join(os.path.dirname(__file__), "_build/logo")
# those are the options for resizing versions without tail or text
svg_sizes = {}
svg_sizes['notail'] = {
"prefix":"notail", "dx":-70, "dy":-20, "size":690,
"title":"SymPy Logo, with no tail"}
svg_sizes['notail-notext'] = {
"prefix":"notailtext", "dx":-70, "dy":60, "size":690,
"title":"SymPy Logo, with no tail, no text"}
svg_sizes['notext'] = {
"prefix":"notext", "dx":-7, "dy":90, "size":750,
"title":"SymPy Logo, with no text"}
svg_sizes['notail'] = {"prefix":"notail", "dx":-70, "dy":-20, "size":690, "title":"SymPy Logo, with no tail"}
svg_sizes['notail-notext'] = {"prefix":"notailtext", "dx":-70, "dy":60, "size":690, "title":"SymPy Logo, with no tail, no text"}
svg_sizes['notext'] = {"prefix":"notext", "dx":-7, "dy":90, "size":750, "title":"SymPy Logo, with no text"}
# The list of identifiers of various versions
versions = ['notail', 'notail-notext', 'notext']
parser = ArgumentParser(usage="%(prog)s [options ...]")
parser = OptionParser()
parser.set_usage("%s [options ...]")
parser.add_argument("--source-dir", type=str, dest="source_dir",
help="Directory of the source *.svg file [default: %(default)s]",
parser.add_option("--source-dir", type="string", dest="source_dir",
help="Directory of the source *.svg file [default: %default]",
default=default_source_dir)
parser.add_argument("--source-svg", type=str, dest="source_svg",
help="File name of the source *.svg file [default: %(default)s]",
parser.add_option("--source-svg", type="string", dest="source_svg",
help="File name of the source *.svg file [default: %default]",
default=default_source_svg)
parser.add_argument("--svg", action="store_true", dest="generate_svg",
help="Generate *.svg versions without tails " \
"and without text 'SymPy' [default: %(default)s]",
parser.add_option("--svg", action="store_true", dest="generate_svg",
help="Generate *.svg versions without tails and without text 'SymPy' [default: %default]",
default=False)
parser.add_argument("--png", action="store_true", dest="generate_png",
help="Generate *.png versions [default: %(default)s]",
parser.add_option("--png", action="store_true", dest="generate_png",
help="Generate *.png versions [default: %default]",
default=False)
parser.add_argument("--ico", action="store_true", dest="generate_ico",
help="Generate *.ico versions [default: %(default)s]",
parser.add_option("--ico", action="store_true", dest="generate_ico",
help="Generate *.ico versions [default: %default]",
default=False)
parser.add_argument("--clear", action="store_true", dest="clear",
help="Remove temporary files [default: %(default)s]",
parser.add_option("--clear", action="store_true", dest="clear",
help="Remove temporary files [default: %default]",
default=False)
parser.add_argument("-a", "--all", action="store_true", dest="generate_all",
help="Shorthand for '--svg --png --ico --clear' options " \
"[default: %(default)s]",
parser.add_option("-a", "--all", action="store_true", dest="generate_all",
help="Shorthand for '--svg --png --ico --clear' options [default: %default]",
default=True)
parser.add_argument("-s", "--sizes", type=str, dest="sizes",
help="Sizes of png pictures [default: %(default)s]",
parser.add_option("-s", "--sizes", type="string", dest="sizes",
help="Sizes of png pictures [default: %default]",
default="160,500")
parser.add_argument("--icon-sizes", type=str, dest="icon_sizes",
help="Sizes of icons embedded in favicon file [default: %(default)s]",
parser.add_option("--icon-sizes", type="string", dest="icon_sizes",
help="Sizes of icons embedded in favicon file [default: %default]",
default="16,32,48,64")
parser.add_argument("--output-dir", type=str, dest="output_dir",
help="Output dir [default: %(default)s]",
parser.add_option("--output-dir", type="string", dest="output_dir",
help="Outpu dir [default: %default]",
default=default_output_dir)
parser.add_argument("-d", "--debug", action="store_true", dest="debug",
help="Print debug log [default: %(default)s]",
parser.add_option("-d", "--debug", action="store_true", dest="debug",
default=False)
def main():
options, args = parser.parse_known_args()
options, args = parser.parse_args()
if options.debug:
logging.basicConfig(level=logging.DEBUG)
@@ -135,9 +126,7 @@ def generate_notail_notext_versions(fn_source, output_dir):
title.firstChild.data = properties["title"]
desc = svg.getElementsByTagName("desc")[0]
desc.appendChild(
doc.createTextNode(
"\n\nThis file is generated from %s !" % fn_source))
desc.appendChild(doc.createTextNode("\n\nThis file is generated from %s !" % fn_source))
fn_out = get_svg_filename_from_versionkey(fn_source, ver)
fn_out = os.path.join(output_dir, fn_out)
@@ -153,8 +142,7 @@ def convert_to_png(fn_source, output_dir, sizes):
stderr=subprocess.STDOUT)
p.communicate()
if p.returncode == 127:
logging.error(
"%s: command not found. Install librsvg" % cmd)
logging.error("%s: command not found" % cmd)
sys.exit(p.returncode)
for ver in svgs:
@@ -199,7 +187,7 @@ def convert_to_ico(fn_source, output_dir, sizes):
stderr=subprocess.STDOUT)
p.communicate()
if p.returncode == 127:
logging.error("%s: command not found. Install imagemagick" % cmd)
logging.error("%s: command not found" % cmd)
sys.exit(p.returncode)
for ver in svgs:
+2 -2
View File
@@ -23,7 +23,7 @@ this will generate isympy.1 in the current directory. -->
<!-- TITLE should be something like "User commands", -->
<!-- "&dhpackage; command-line reference" or similar (see e.g. -->
<!-- https://www.tldp.org/HOWTO/Man-Page/q2.html). But limit -->
<!-- http://www.tldp.org/HOWTO/Man-Page/q2.html). But limit -->
<!-- the length to 30 chars. -->
<!ENTITY dhtitle "&dhpackage; command-line reference">
@@ -36,7 +36,7 @@ this will generate isympy.1 in the current directory. -->
<!-- SECTION should be 1-8, maybe w/ subsection other -->
<!-- parameters are allowed: see man(7), man(1) and -->
<!-- https://www.tldp.org/HOWTO/Man-Page/q2.html. -->
<!-- http://www.tldp.org/HOWTO/Man-Page/q2.html. -->
<!ENTITY dhsection "1">
]>
+2 -4
View File
@@ -9,8 +9,8 @@
*
*/
@import url("classic.css");
@import url(https://fonts.googleapis.com/css?family=Open+Sans);
@import url("basic.css");
@import url(http://fonts.googleapis.com/css?family=Open+Sans);
/* -- page layout ----------------------------------------------------------- */
@@ -290,8 +290,6 @@ p.admonition-title:after {
}
pre {
font-family: DejaVu Sans Mono, monospace;
font-size: 100%;
padding: 5px;
background-color: {{ theme_codebgcolor }};
color: {{ theme_codetextcolor }};
+1 -1
View File
@@ -1,6 +1,6 @@
{% extends '!layout.html' %}
{%- block linktags %}
<link href="https://docs.sympy.org/latest/{{ pagename }}.html" rel="canonical" />
<link href="http://docs.sympy.org/latest/{{ pagename }}.html" rel="canonical" />
{{ super() }}
{%- endblock %}
+6 -6
View File
@@ -12,9 +12,9 @@ You can find a brief history of SymPy in the `README <https://github.com/sympy/s
Financial and Infrastructure Support
------------------------------------
* `Google <https://www.google.com/about/company/>`_: SymPy has received generous
* `Google <http://www.google.com/about/company/>`_: SymPy has received generous
financial support from Google in various years through the `Google Summer of
Code <https://g.co/gsoc>`_ program by providing stipends:
Code <http://g.co/gsoc>`_ program by providing stipends:
* in 2007 for 5 students (`GSoC 2007 <https://github.com/sympy/sympy/wiki/GSoC-2007-Report>`_)
* in 2008 for 1 student (`GSoC 2008 <https://github.com/sympy/sympy/wiki/GSoC-2008-report>`_)
@@ -40,14 +40,14 @@ Financial and Infrastructure Support
* 6 GSoC 2015 students
* 1 GSoC 2016 student (James)
* `Portland State University (PSU) <https://www.pdx.edu/>`_ has hosted following
* `Portland State University (PSU) <http://www.pdx.edu/>`_ has hosted following
GSoC students:
* 1 student (Chris) in 2007
* 3 students (Aaron, Dale and Fabian) in 2009
* 1 student (Addison) in 2010
* `The Space Telescope Science Institute <http://www.stsci.edu/>`_: STScI hosted 1 GSoC 2007 student (Mateusz)
* `The Space Telescope Science Institute <http://www.stsci.edu/portal/>`_: STScI hosted 1 GSoC 2007 student (Mateusz)
* `The Ruby Science Foundation <http://www.sciruby.com/>`_ has hosted following
GSoC students:
@@ -57,8 +57,8 @@ Financial and Infrastructure Support
* Several 13-17 year old pre-university students contributed as part of
Google's `Code-In
<https://www.google-melange.com/gci/homepage/google/gci2011>`_ 2011. (`GCI
2011 <https://www.google-melange.com/gci/org/google/gci2011/sympy>`_)
<http://www.google-melange.com/gci/homepage/google/gci2011>`_ 2011. (`GCI
2011 <http://www.google-melange.com/gci/org/google/gci2011/sympy>`_)
* `Simula Research Laboratory <https://www.simula.no/>`_: supports Pearu Peterson work in SymPy/SymPy Core projects
+7 -93
View File
@@ -12,9 +12,6 @@
# serve to show the default value.
import sys
import inspect
import os
import subprocess
import sympy
# If your extensions are in another directory, add it here.
@@ -25,9 +22,8 @@ sys.path = ['ext'] + sys.path
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.addons.*') or your custom ones.
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.linkcode', 'sphinx_math_dollar',
'sphinx.ext.mathjax', 'numpydoc', 'sympylive',
'sphinx.ext.graphviz', 'matplotlib.sphinxext.plot_directive']
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode', 'sphinx.ext.mathjax',
'numpydoc', 'sympylive', 'sphinx.ext.graphviz', ]
# Use this to use pngmath instead
#extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode', 'sphinx.ext.pngmath', ]
@@ -35,10 +31,8 @@ extensions = ['sphinx.ext.autodoc', 'sphinx.ext.linkcode', 'sphinx_math_dollar',
# To stop docstrings inheritance.
autodoc_inherit_docstrings = False
# MathJax file, which is free to use. See https://www.mathjax.org/#gettingstarted
# As explained in the link using latest.js will get the latest version even
# though it says 2.7.5.
mathjax_path = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS_HTML-full'
# MathJax file, which is free to use. See http://www.mathjax.org/docs/2.0/start.html
mathjax_path = 'http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML-full'
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
@@ -53,7 +47,7 @@ suppress_warnings = ['ref.citation', 'ref.footnote']
# General substitutions.
project = 'SymPy'
copyright = '2019 SymPy Development Team'
copyright = '2018 SymPy Development Team'
# The default replacements for |version| and |release|, also used in various
# other places throughout the built documents.
@@ -86,8 +80,6 @@ today_fmt = '%B %d, %Y'
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# Don't show the source code hyperlinks when using matplotlib plot directive.
plot_html_show_source_link = False
# Options for HTML output
# -----------------------
@@ -110,7 +102,7 @@ html_theme = 'classic'
html_logo = '_static/sympylogo.png'
html_favicon = '../_build/logo/sympy-notailtext-favicon.ico'
# See http://www.sphinx-doc.org/en/master/theming.html#builtin-themes
# See http://sphinx-doc.org/theming.html#builtin-themes.
# If true, SmartyPants will be used to convert quotes and dashes to
@@ -207,83 +199,5 @@ texinfo_documents = [
]
# Use svg for graphviz
graphviz_output_format = 'svg'
# Requried for linkcode extension.
# Get commit hash from the external file.
commit_hash_filepath = '../commit_hash.txt'
commit_hash = None
if os.path.isfile(commit_hash_filepath):
with open(commit_hash_filepath, 'r') as f:
commit_hash = f.readline()
# Get commit hash from the external file.
if not commit_hash:
try:
commit_hash = subprocess.check_output(['git', 'rev-parse', 'HEAD'])
commit_hash = commit_hash.decode('ascii')
commit_hash = commit_hash.rstrip()
except:
import warnings
warnings.warn(
"Failed to get the git commit hash as the command " \
"'git rev-parse HEAD' is not working. The commit hash will be " \
"assumed as the SymPy master, but the lines may be misleading " \
"or nonexistent as it is not the correct branch the doc is " \
"built with. Check your installation of 'git' if you want to " \
"resolve this warning.")
commit_hash = 'master'
fork = 'sympy'
blobpath = \
"https://github.com/{}/sympy/blob/{}/sympy/".format(fork, commit_hash)
def linkcode_resolve(domain, info):
"""Determine the URL corresponding to Python object."""
if domain != 'py':
return
modname = info['module']
fullname = info['fullname']
submod = sys.modules.get(modname)
if submod is None:
return
obj = submod
for part in fullname.split('.'):
try:
obj = getattr(obj, part)
except Exception:
return
# strip decorators, which would resolve to the source of the decorator
# possibly an upstream bug in getsourcefile, bpo-1764286
try:
unwrap = inspect.unwrap
except AttributeError:
pass
else:
obj = unwrap(obj)
try:
fn = inspect.getsourcefile(obj)
except Exception:
fn = None
if not fn:
return
try:
source, lineno = inspect.getsourcelines(obj)
except Exception:
lineno = None
if lineno:
linespec = "#L%d-L%d" % (lineno, lineno + len(source) - 1)
else:
linespec = ""
fn = os.path.relpath(fn, start=os.path.dirname(sympy.__file__))
return blobpath + fn + linespec
+9 -9
View File
@@ -20,7 +20,7 @@ remainder of the SymPy Docs, and the `official Python Tutorial <https://docs.pyt
If you are already familiar with C or Java, you might also want to look
at this `4 minute Python tutorial
<https://nerdparadise.com/programming/python4minutes/>`_.
<http://www.nerdparadise.com/tech/python/4minutecrashcourse/>`_.
Ignore ``#doctest: +SKIP`` in the examples. That has to do with
internal testing of the examples.
@@ -230,7 +230,7 @@ are used for the imaginary unit (:math:`i`), the base of the natural
logarithm (:math:`e`), the :func:`sympify` function (see :ref:`Symbolic
Expressions<symbolic-expressions>` below), numeric evaluation (:func:`N`
is equivalent to :ref:`evalf()<evalf-label>` ),
the `big O <https://en.wikipedia.org/wiki/Big_O_notation>`_ order symbol
the `big O <http://en.wikipedia.org/wiki/Big_O_notation>`_ order symbol
(as in :math:`O(n\log{n})`), and the assumptions object that holds a list of
supported ask keys (such as :obj:`Q.real`), respectively. You can use the
mnemonic ``OSINEQ`` to remember what Symbols are defined by default in SymPy.
@@ -258,10 +258,10 @@ To get a full list of all default names in SymPy do:
# A big list of all default sympy names and functions follows.
# Ignore everything that starts and ends with __.
If you have `IPython <https://ipython.org/>`_ installed and
If you have `IPython <http://ipython.org/>`_ installed and
use :command:`isympy`, you can also press the TAB key to get a list of
all built-in names and to autocomplete. Also, see `this page
<https://kogs-www.informatik.uni-hamburg.de/~meine/python_tricks>`_ for a
<http://kogs-www.informatik.uni-hamburg.de/~meine/python_tricks>`_ for a
trick for getting tab completion in the regular Python console.
.. note::
@@ -334,9 +334,9 @@ you don't have to worry about this problem:
3.142857142857143
>>> # One solution is to just assign the expression to a variable
>>> # if we need to use it again.
>>> a = solve(7*x - 22, x)[0]
>>> a = solve(7*x - 22, x)
>>> a
22/7
[22/7]
The other solution is to put quotes around the expression
and run it through S() (i.e., sympify it):
@@ -346,7 +346,7 @@ you don't have to worry about this problem:
Also, if you do not use :command:`isympy`, you could use ``from
__future__ import division`` to prevent the ``/`` sign from performing
`integer division <https://en.wikipedia.org/wiki/Integer_division>`_.
`integer division <http://en.wikipedia.org/wiki/Integer_division>`_.
>>> from __future__ import division
>>> 1/2 # With division imported it evaluates to a python float
@@ -740,8 +740,8 @@ Getting help from within SymPy
help()
------
Although all docs are available at `docs.sympy.org <https://docs.sympy.org/>`_ or on the
`SymPy Wiki <https://wiki.sympy.org/>`_, you can also get info on functions from within the
Although all docs are available at `docs.sympy.org <http://docs.sympy.org/>`_ or on the
`SymPy Wiki <http://wiki.sympy.org/>`_, you can also get info on functions from within the
Python interpreter that runs SymPy. The easiest way to do this is to do
``help(function)``, or ``function?`` if you are using :command:`ipython`::
+1 -1
View File
@@ -127,7 +127,7 @@ For easier use, there is a syntactic sugar for expressions.
For example, ``cos(x) + 1`` is equal to ``cos(x).__add__(1)`` is equal to
``Add(cos(x), Integer(1))``
This works because Python allows you to override the behavior of built-in
This works becauses Python allows you to override the behavior of built-in
operations ``+, *, -, /`` etc., by defining methods with names ``__add__``,
``__mul__`` etc., so ``cos(x) + 1`` is evaluated as ``cos(x).__add__(1)``.
+2 -3
View File
@@ -1,5 +1,3 @@
.. _documentation:
.. SymPy documentation master file, created by sphinx-quickstart.py on Sat Mar 22 19:34:32 2008.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
@@ -9,7 +7,7 @@ Welcome to SymPy's documentation!
A PDF version of these docs can be found `here <https://github.com/sympy/sympy/releases>`_.
`SymPy <https://sympy.org>`_ is a Python library for symbolic mathematics.
`SymPy <http://sympy.org>`_ is a Python library for symbolic mathematics.
If you are new to SymPy, start with the :ref:`Tutorial <tutorial>`.
This is the central page for all of SymPy's documentation.
@@ -26,6 +24,7 @@ Contents:
guide.rst
modules/index.rst
special_topics/index.rst
python-comparisons.rst
wiki.rst
outreach.rst
aboutus.rst
+11 -15
View File
@@ -5,16 +5,17 @@ Installation
The SymPy CAS can be installed on virtually any computer with Python 2.7 or
above. SymPy does require `mpmath`_ Python library to be installed first. The
recommended method of installation is through Anaconda, which includes
mpmath, as well as several other useful libraries. Alternatively, some Linux
distributions have SymPy packages available.
current recommended method of installation is through Anaconda, which includes
mpmath, as well as several other useful libraries. Alternatively, executables
are available for Windows, and some Linux distributions have SymPy packages
available.
SymPy officially supports Python 2.7, 3.5, 3.6, 3.7, and PyPy.
SymPy officially supports Python 2.7, 3.4, 3.5, 3.6 and PyPy.
Anaconda
========
`Anaconda <https://www.anaconda.com/download/>`_ is a free Python distribution from
`Anaconda <http://continuum.io/downloads>`_ is a free Python distribution from
Continuum Analytics that includes SymPy, Matplotlib, IPython, NumPy, and many
more useful packages for scientific computing. This is recommended because
many nice features of SymPy are only enabled when certain libraries are
@@ -34,7 +35,7 @@ If you wish to contribute to SymPy or like to get the latest updates as they
come, install SymPy from git. To download the repository, execute the
following from the command line::
git clone https://github.com/sympy/sympy.git
git clone git://github.com/sympy/sympy.git
To update to the latest version, go into your repository and execute::
@@ -43,7 +44,7 @@ To update to the latest version, go into your repository and execute::
If you want to install SymPy, but still want to use the git version, you can run
from your repository::
python setupegg.py develop
setupegg.py develop
This will cause the installed version to always point to the version in the git
directory.
@@ -51,14 +52,9 @@ directory.
Other Methods
=============
You may also install SymPy using pip or from source. In addition, most Linux
and Python distributions have some SymPy version available to install using
their package manager. Here is a list of several such Python distributions:
* `Anaconda <https://www.anaconda.com/download/>`_
* `Enthought Canopy <https://www.enthought.com/product/canopy/>`_
* `ActivePython <https://www.activestate.com/activepython>`_
* `Spack <https://spack.io/>`_
An installation executable (.exe) is available for Windows users at the
`downloads site`_. In addition, various Linux distributions have SymPy
available as a package. You may also install SymPy from source or using pip.
Run SymPy
=========
+1 -1
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (https://www.inkscape.org/) -->
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://web.resource.org/cc/"

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

+1 -1
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (https://www.inkscape.org/) -->
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

-19
View File
@@ -1,19 +0,0 @@
========
Algebras
========
Introduction
------------
The Algebras module for SymPy provides support
for basic algebraic operations on Quaternions.
Quaternion Reference
--------------------
.. automodule:: sympy.algebras
This section lists the classes implemented by the Algebras module.
.. autoclass:: Quaternion
:members:
@@ -1,6 +0,0 @@
======
Common
======
.. automodule:: sympy.assumptions.handlers.common
:members:
@@ -11,8 +11,6 @@ Contents
:maxdepth: 3
calculus.rst
common.rst
matrices.rst
ntheory.rst
order.rst
sets.rst
@@ -1,6 +0,0 @@
========
Matrices
========
.. automodule:: sympy.assumptions.handlers.matrices
:members:
+4 -6
View File
@@ -1,8 +1,6 @@
.. _assumptions_module:
===========
Assumptions
===========
==================
Assumptions module
==================
.. automodule:: sympy.assumptions
@@ -123,7 +121,7 @@ in notable speed improvements.
Logic inference used in one ask could be used to speed up further queries, and
current system does not take advantage of this. For example, a truth maintenance
system (https://en.wikipedia.org/wiki/Truth_maintenance_system) could be implemented.
system (http://en.wikipedia.org/wiki/Truth_maintenance_system) could be implemented.
Misc
====
+1 -6
View File
@@ -10,10 +10,5 @@ Calculus
.. automodule:: sympy.calculus.singularities
:members:
.. _finite_diff:
.. automodule:: sympy.calculus.finite_diff
:members:
.. automodule:: sympy.calculus.util
.. automodule :: sympy.calculus.finite_diff
:members:
+2 -3
View File
@@ -1,6 +1,5 @@
===============
Category Theory
===============
Category Theory Module
======================
Introduction
------------
+42 -90
View File
@@ -1,8 +1,8 @@
.. _codegen_prose:
===============
Code Generation
===============
================================================
Structural Details of Code Generation with SymPy
================================================
Several submodules in SymPy allow one to generate directly compilable and
executable code in a variety of different programming languages from SymPy
@@ -56,23 +56,37 @@ Code printers (sympy.printing)
------------------------------
This is where the meat of code generation is; the translation of SymPy
expressions to specific languages. Supported languages are C
(:py:func:`sympy.printing.ccode.ccode`), R
(:py:func:`sympy.printing.rcode.rcode`), Fortran 95
(:py:func:`sympy.printing.fcode.fcode`), JavaScript
(:py:func:`sympy.printing.jscode.jscode`), Julia
(:py:func:`sympy.printing.julia.julia_code`), Mathematica
(:py:func:`sympy.printing.mathematica.mathematica_code`), Octave/Matlab
(:py:func:`sympy.printing.octave.octave_code`), Rust
(:py:func:`sympy.printing.rust.rust_code`), Python (print_python, which is
actually more like a lightweight version of codegen for Python, and
Python (:py:func:`sympy.printing.pycode.pycode`), and
:py:func:`sympy.printing.lambdarepr.lambdarepr`, which supports many libraries
(like NumPy), and theano
(:py:func:`sympy.printing.theanocode.theano_function`). The code printers are
special cases of the other prints in SymPy (str printer, pretty printer, etc.).
An important distinction is that the code printer has to deal with assignments
(using the :class:`sympy.codegen.ast.Assignment` object). This serves as
(using the :class:`sympy.printing.codeprinter.Assignment` object).This serves as
building blocks for the code printers and hence the ``codegen`` module. An
example that shows the use of ``Assignment`` in C code::
example that shows the use of ``Assignment``::
>>> from sympy.codegen.ast import Assignment
>>> print(ccode(Assignment(x, y + 1)))
x = y + 1;
>>> mat = Matrix([x, y, z]).T
>>> known_mat = MatrixSymbol('K', 1, 3)
>>> Assignment(known_mat, mat)
K := [x y z]
>>> Assignment(known_mat, mat).lhs
K
>>> Assignment(known_mat, mat).rhs
[x y z]
Here is another simple example of printing a C version of a SymPy expression::
Here is a simple example of printing a C version of a SymPy expression::
>>> expr = (Rational(-1, 2) * Z * k * (e**2) / r)
>>> expr
@@ -164,8 +178,8 @@ An example of Mathematica code printer::
>>> expr = summation(expr, (n, -1, 1))
>>> mathematica_code(expr)
T*(x[-T]*Sin[(T + t)/T]/(T + t) + x[T]*Sin[(-T + t)/T]/(-T + t) + x[0]*Sin[t/T
]/t)
T*x[-T]*Sin[(T + t)/T]/(T + t) + T*x[T]*Sin[(-T + t)/T]/(-T + t) + T*x[0]*Sin[
t/T]/t
We can go through a common expression in different languages we support and see
how it works::
@@ -289,12 +303,12 @@ For example::
>>> [arg.result_var for arg in routine.results] # doctest: +SKIP
[result₅₁₄₂₃₄₁₆₈₁₃₉₇₇₁₉₄₂₈]
>>> [arg.expr for arg in routine.results]
⎡ __________ ⎤
⎢ y ╱ (2 - y)! -2⋅x ⎥
⎢4⋅√6⋅(4⋅x) ⋅ ╱ ──────── ⋅ℯ ⋅assoc_laguerre(2 - y, 2⋅y + 1, 4⋅x)⎥
⎢ ╲╱ (y + 3)! ⎥
⎢────────────────────────────────────────────────────────────────────⎥
⎣ 3 ⎦
⎡ ___________ ⎤
⎢ y ╱ (-y + 2)! -2⋅x ⎥
⎢4⋅√6⋅(4⋅x) ⋅ ╱ ───────── ⋅ℯ ⋅assoc_laguerre(-y + 2, 2⋅y + 1, 4⋅x)⎥
⎢ ╲╱ (y + 3)! ⎥
⎢──────────────────────────────────────────────────────────────────────⎥
⎣ 3 ⎦
>>> [arg.name for arg in routine.arguments]
[x, y]
@@ -486,7 +500,7 @@ implies 'Universal functions' and follows an ideology set by NumPy. The main
point of ufuncify as compared to autowrap is that it allows arrays as arguments
and can operate in an element-by-element fashion. The core operation done
element-wise is in accordance to Numpy's array broadcasting rules. See `this
<https://docs.scipy.org/doc/numpy/reference/ufuncs.html>`_ for more.
<http://docs.scipy.org/doc/numpy/reference/ufuncs.html>`_ for more.
>>> from sympy import *
>>> from sympy.abc import x
@@ -498,16 +512,16 @@ element-wise is in accordance to Numpy's array broadcasting rules. See `this
This function ``f`` consumes and returns a NumPy array. Generally ``ufuncify``
performs at least as well as ``lambdify``. If the expression is complicated
then ``ufuncify`` often significantly outperforms the NumPy backed solution.
Jensen has a good `blog post <https://ojensen.wordpress.com/2010/08/10/fast-ufunc-ish-hydrogen-solutions/>`_ on this topic.
Jensen has a good `blog post <http://ojensen.wordpress.com/2010/08/10/fast-ufunc-ish-hydrogen-solutions/>`_ on this topic.
Let us see an example for some quantitative analysis::
>>> from sympy.physics.hydrogen import R_nl
>>> expr = R_nl(3, 1, x, 6)
>>> expr
-2⋅x
8⋅x⋅(4 - 4⋅x)⋅ℯ
───────────────────
-2⋅x
8⋅x⋅(-4⋅x + 4)⋅ℯ
────────────────────
3
The lambdify function translates SymPy expressions into Python functions,
@@ -542,19 +556,17 @@ There are other facilities available with SymPy to do efficient numeric
computation. See :ref:`this<numeric_computation>` page for a comparison among them.
Classes and functions for rewriting expressions (sympy.codegen.rewriting)
-------------------------------------------------------------------------
Special (finite precision arithmetic) math functions
----------------------------------------------------
.. automodule:: sympy.codegen.rewriting
.. automodule:: sympy.codegen.cfunctions
:members:
.. automodule:: sympy.codegen.matrix_nodes
:members:
Tools for simplifying expressions using approximations (sympy.codegen.approximations)
-------------------------------------------------------------------------------------
Fortran specific functions
--------------------------
.. automodule:: sympy.codegen.approximations
.. automodule:: sympy.codegen.ffunctions
:members:
Classes for abstract syntax trees (sympy.codegen.ast)
@@ -562,63 +574,3 @@ Classes for abstract syntax trees (sympy.codegen.ast)
.. automodule:: sympy.codegen.ast
:members:
Special C math functions (sympy.codegen.cfunctions)
---------------------------------------------------
.. automodule:: sympy.codegen.cfunctions
:members:
C specific AST nodes (sympy.codegen.cnodes)
-------------------------------------------
.. automodule:: sympy.codegen.cnodes
:members:
C++ specific AST nodes (sympy.codegen.cxxnodes)
-----------------------------------------------
.. automodule:: sympy.codegen.cxxnodes
:members:
Fortran specific AST nodes (sympy.codegen.fnodes)
-------------------------------------------------
.. automodule:: sympy.codegen.fnodes
:members:
Algorithms (sympy.codegen.algorithms)
-------------------------------------
.. automodule:: sympy.codegen.algorithms
:members:
Python utilities (sympy.codegen.pyutils)
----------------------------------------
.. automodule:: sympy.codegen.pyutils
:members:
C utilities (sympy.codegen.cutils)
----------------------------------
.. automodule:: sympy.codegen.cutils
:members:
Fortran utilities (sympy.codegen.futils)
----------------------------------------
.. automodule:: sympy.codegen.futils
:members:
Array utilities (sympy.codegen.array_utils)
-------------------------------------------
.. automodule:: sympy.codegen.array_utils
:members:
+8 -8
View File
@@ -42,7 +42,7 @@ returned.
Example of construction of a finitely-presented group.
The symmetric group of degree 4 may be represented as a two generator group
with presentation `\left\langle a, b \mid a^2, b^3, (ab)^4 \right\rangle`. Giving the relations as a
with presentation `\langle a, b \mid a^2, b^3, (ab)^4 \rangle`. Giving the relations as a
list of relators, group in SymPy would be specified as:
>>> F, a, b = free_group("a, b")
@@ -51,7 +51,7 @@ list of relators, group in SymPy would be specified as:
<fp group on the generators (a, b)>
Currently groups with relators having presentation like
`\left\langle r, s, t \mid r^2, s^2, t^2, rst = str = trs \right\rangle` will have to be specified as:
`\langle r, s, t \mid r^2, s^2, t^2, rst = str = trs \rangle` will have to be specified as:
>>> F, r, s, t = free_group("r, s, t")
>>> G = FpGroup(F, [r**2, s**2, t**2, r*s*t*r**-1*t**-1*s**-1, s*t*r*s**-1*r**-1*t**-1])
@@ -174,12 +174,12 @@ manipulate the algorithm, like
have finite index, and even if it has it may take many more intermediate
cosets than the actual index of the subgroup is. To avoid a coset enumeration
"running away" therefore SymPy has a "safety stop" built-in. This is
controlled by this variable. To change it, use `max_cosets` keyword.
For example:
controlled by this variable. For example:
>>> CosetTable.coset_table_max_limit = 50
>>> F, a, b = free_group("a, b")
>>> Cox = FpGroup(F, [a**6, b**6, (a*b)**2, (a**2*b**2)**2, (a**3*b**3)**5])
>>> C_r = coset_enumeration_r(Cox, [a], max_cosets=50)
>>> C_r = coset_enumeration_r(Cox, [a])
Traceback (most recent call last):
...
ValueError: the coset enumeration has defined more than 50 cosets
@@ -209,12 +209,12 @@ whose index does not exceed some (modest) integer bound.
Low Index Subgroups
```````````````````
``low_index_subgroups(G, N)``: Given a finitely presented group `G = \left\langle X \mid R \right\rangle`
``low_index_subgroups(G, N)``: Given a finitely presented group `G = \langle X \mid R \rangle`
(can be a free group), and ``N`` a positive integer, determine the conjugacy classes of
subgroups of ``G`` whose indices is less than or equal to ``N``.
For example to find all subgroups of `G = \left\langle a, b \mid a^2 = b^3 = (ab)^4 = 1 \right\rangle`
having index `\le` 4, can be found as follows:
For example to find all subgroups of `G = \langle a, b \mid a^2 = b^3 = (ab)^4 = 1 \rangle`
having index <= 4, can be found as follows:
>>> from sympy.combinatorics.fp_groups import low_index_subgroups
>>> F, a, b = free_group("a, b")
+3 -4
View File
@@ -1,8 +1,8 @@
.. _combinatiorics-docs:
=============
Combinatorics
=============
====================
Combinatorics Module
====================
Contents
========
@@ -23,4 +23,3 @@ Contents
testutil.rst
tensor_can.rst
fp_groups.rst
pc_groups.rst
-307
View File
@@ -1,307 +0,0 @@
Polycyclic Groups
=================
Introduction
------------
This module presents the functionality designed for computing with
polycyclic groups(PcGroup for short). The name of the corresponding
SymPy object is ``PolycyclicGroup``. The functions or classes described
here are studied under **Computational Group Theory**.
Overview of functionalities
```````````````````````````
* The construction of PolycyclicGroup from a given PermutationGroup.
* Computation of polycyclic generating sequence(pcgs for short) and
polycyclic series(pc_series).
* Computation of relative order for polycyclic series.
* Implementation of class Collector which can be treated as a base for polycylic groups.
* Implementation of polycyclic group presentation(pc_presentation for short).
* Computation of exponent vector, depth and leading exponent for a given element
of a polycyclic group.
For a description of fundamental algorithms of polycyclic groups, we
often make use of *Handbook of Computational Group Theory*.
The Construction of Polycyclic Groups
-------------------------------------
Given a Permutation Group, A Polycyclic Group is constructed by computing the
corresponding polycylic generating sequence, polycyclic series and it's
relative order.
Attributes of PolycyclicGroup
`````````````````````````````
* ``pc_sequence`` : Polycyclic sequence is formed by collecting all the missing
generators between the adjacent groups in the derived series of given
permutation group.
* ``pc_series`` : Polycyclic series is formed by adding all the missing generators
of ``der[i+1]`` in ``der[i]``, where ``der`` represents derived series.
* ``relative_order`` : A list, computed by the ratio of adjacent groups in pc_series.
* ``collector`` : By default, it is None. Collector class provides the polycyclic presentation.
>>> from sympy.combinatorics.named_groups import SymmetricGroup
>>> G = SymmetricGroup(4)
>>> PcGroup = G.polycyclic_group()
>>> len(PcGroup.pcgs)
4
>>> pc_series = PcGroup.pc_series
>>> pc_series[0]==G
True
>>> gen = pc_series[len(pc_series)-1].generators[0]
>>> gen.is_identity
True
>>> PcGroup.relative_order
[2, 3, 2, 2]
The Construction of Collector
-----------------------------
Collector is one of the attributes of class PolycyclicGroup.
Attributes of Collector
```````````````````````
Collector posses all the attributes of PolycyclicGroup, In addition there are
few more attributes which are defined below:
* ``free_group`` : free_group provides the mapping of polycyclic generating sequence with
the free group elements.
* ``pc_presentation`` : Provides the presentation of polycyclic groups with the
help of power and conjugate relators.
>>> from sympy.combinatorics.named_groups import SymmetricGroup
>>> G = SymmetricGroup(3)
>>> PcGroup = G.polycyclic_group()
>>> Collector = PcGroup.collector
>>> Collector.free_group
<free group on the generators (x0, x1)>
>>> Collector.pc_presentation
{x0**2: (), x1**3: (), x0**-1*x1*x0: x1**2}
Computation of Minimal Uncollected Subword
``````````````````````````````````````````
A word ``V`` defined on generators in the free_group of pc_group is a minimal
uncollected subword of the word ``W`` if ``V`` is a subword of ``W`` and it has one of
the following form:
* `v = {x_{i+1}}^{a_j}x_i`
* `v = {x_{i+1}}^{a_j}{x_i}^{-1}`
* `v = {x_i}^{a_j}`
`a_j \notin \{0, \ldots \mathrm{relative\_order}[j]-1\}`.
>>> from sympy.combinatorics.named_groups import SymmetricGroup
>>> from sympy.combinatorics.free_groups import free_group
>>> G = SymmetricGroup(4)
>>> PcGroup = G.polycyclic_group()
>>> collector = PcGroup.collector
>>> F, x1, x2 = free_group("x1, x2")
>>> word = x2**2*x1**7
>>> collector.minimal_uncollected_subword(word)
((x2, 2),)
Computation of Subword Index
````````````````````````````
For a given word and it's subword, subword_index computes the
starting and ending index of the subword in the word.
>>> from sympy.combinatorics.named_groups import SymmetricGroup
>>> from sympy.combinatorics.free_groups import free_group
>>> G = SymmetricGroup(4)
>>> PcGroup = G.polycyclic_group()
>>> collector = PcGroup.collector
>>> F, x1, x2 = free_group("x1, x2")
>>> word = x2**2*x1**7
>>> w = x2**2*x1
>>> collector.subword_index(word, w)
(0, 3)
>>> w = x1**7
>>> collector.subword_index(word, w)
(2, 9)
Computation of Collected Word
`````````````````````````````
A word ``W`` is called collected, if ``W`` `= {x_{i_1}}^{a_1} \ldots {x_{i_r}}^{a_r}`
with `i_1 < i_2< \ldots < i_r` and `a_j` is in `\{1 \ldots s_{j-1}\}`, where `s_j`
represents the respective relative order.
>>> from sympy.combinatorics.named_groups import SymmetricGroup
>>> from sympy.combinatorics.perm_groups import PermutationGroup
>>> from sympy.combinatorics.free_groups import free_group
>>> G = SymmetricGroup(4)
>>> PcGroup = G.polycyclic_group()
>>> collector = PcGroup.collector
>>> F, x0, x1, x2, x3 = free_group("x0, x1, x2, x3")
>>> word = x3*x2*x1*x0
>>> collected_word = collector.collected_word(word)
>>> free_to_perm = {}
>>> free_group = collector.free_group
>>> for sym, gen in zip(free_group.symbols, collector.pcgs):
... free_to_perm[sym] = gen
>>> G1 = PermutationGroup()
>>> for w in word:
... sym = w[0]
... perm = free_to_perm[sym]
... G1 = PermutationGroup([perm] + G1.generators)
>>> G2 = PermutationGroup()
>>> for w in collected_word:
... sym = w[0]
... perm = free_to_perm[sym]
... G2 = PermutationGroup([perm] + G2.generators)
>>> G1 == G2
True
Computation of Polycyclic Presentation
--------------------------------------
The computation of presentation starts from the bottom of the pcgs and polycyclic series.
Storing all the previous generators from pcgs and then taking the last generator
as the generator which acts as a conjugator and conjugates all the previous
generators in the list.
To get a clear picture, start with an example of SymmetricGroup(4). For S(4) there are 4
generators in pcgs say `[x_0, x_1, x_2, x_3]` and the relative_order vector is [2, 3, 2, 2].
Starting from bottom of this sequence the presentation is computed in order as below.
using only `[x_3]` from ``pcgs`` and ``pc_series[4]`` compute:
* `x_3^2`
using only `[x_3]` from ``pcgs`` and ``pc_series[3]`` compute:
* `x_2^2`
* `x_2^{-1}x_3x_2`
using `[x_3, x_2]` from ``pcgs`` and ``pc_series[2]`` compute:
* `x_1^3`
* `x_1^{-1}x_3x_1`
* `x_1^{-1}x_2x_1`
using `[x_3, x_2, x_1]` from ``pcgs`` and ``pc_series[1]`` compute:
* `x_0^2`
* `x_0^{-1}x_3x_0`
* `x_0^{-1}x_2x_0`
* `x_0^{-1}x_1x_0`
One thing to note is same group can have different pcgs due to variying derived_series which,
results in different polycyclic presentations.
>>> from sympy.combinatorics.named_groups import SymmetricGroup
>>> from sympy.combinatorics.permutations import Permutation
>>> G = SymmetricGroup(4)
>>> PcGroup = G.polycyclic_group()
>>> collector = PcGroup.collector
>>> pcgs = PcGroup.pcgs
>>> len(pcgs)
4
>>> free_group = collector.free_group
>>> pc_resentation = collector.pc_presentation
>>> free_to_perm = {}
>>> for s, g in zip(free_group.symbols, pcgs):
... free_to_perm[s] = g
>>> for k, v in pc_resentation.items():
... k_array = k.array_form
... if v != ():
... v_array = v.array_form
... lhs = Permutation()
... for gen in k_array:
... s = gen[0]
... e = gen[1]
... lhs = lhs*free_to_perm[s]**e
... if v == ():
... assert lhs.is_identity
... continue
... rhs = Permutation()
... for gen in v_array:
... s = gen[0]
... e = gen[1]
... rhs = rhs*free_to_perm[s]**e
... assert lhs == rhs
Computation of Exponent Vector
------------------------------
Any generator of the polycyclic group can be represented with the help of it's
polycyclic generating sequence. Hence, the length of exponent vector is equal to
the length of the pcgs.
A given generator ``g`` of the polycyclic group, can be represented as
`g = x_1^{e_1} \ldots x_n^{e_n}`, where `x_i` represents polycyclic generators
and ``n`` is the number of generators in the free_group equal to the length of pcgs.
>>> from sympy.combinatorics.named_groups import SymmetricGroup
>>> from sympy.combinatorics.permutations import Permutation
>>> G = SymmetricGroup(4)
>>> PcGroup = G.polycyclic_group()
>>> collector = PcGroup.collector
>>> pcgs = PcGroup.pcgs
>>> collector.exponent_vector(G[0])
[1, 0, 0, 0]
>>> exp = collector.exponent_vector(G[1])
>>> g = Permutation()
>>> for i in range(len(exp)):
... g = g*pcgs[i]**exp[i] if exp[i] else g
>>> assert g == G[1]
Depth of Polycyclic generator
`````````````````````````````
Depth of a given polycyclic generator is defined as the index of the first
non-zero entry in the exponent vector.
>>> from sympy.combinatorics.named_groups import SymmetricGroup
>>> G = SymmetricGroup(3)
>>> PcGroup = G.polycyclic_group()
>>> collector = PcGroup.collector
>>> collector.depth(G[0])
2
>>> collector.depth(G[1])
1
Computation of Leading Exponent
```````````````````````````````
Leading exponent represents the exponent of polycyclic generator at the above depth.
>>> from sympy.combinatorics.named_groups import SymmetricGroup
>>> G = SymmetricGroup(3)
>>> PcGroup = G.polycyclic_group()
>>> collector = PcGroup.collector
>>> collector.leading_exponent(G[1])
1
Bibliography
------------
.. [Ho05] Derek F. Holt,
Handbook of Computational Group Theory.
In the series 'Discrete Mathematics and its Applications',
`Chapman & Hall/CRC 2005, xvi + 514 p <https://www.crcpress.com/Handbook-of-Computational-Group-Theory/Holt-Eick-OBrien/p/book/9781584883722>`_.
+2 -3
View File
@@ -1,6 +1,5 @@
========
Concrete
========
Concrete Mathematics
====================
Hypergeometric terms
--------------------
+3 -10
View File
@@ -1,6 +1,5 @@
====
Core
====
SymPy Core
==========
sympify
-------
@@ -16,7 +15,7 @@ assumptions
.. automodule:: sympy.core.assumptions
cache
-----
-------
.. module:: sympy.core.cache
cacheit
@@ -226,12 +225,6 @@ GoldenRatio
.. autoclass:: GoldenRatio
:members:
TribonacciConstant
^^^^^^^^^^^^^^^^^^
.. autoclass:: TribonacciConstant
:members:
power
-----
.. module:: sympy.core.power
+3 -16
View File
@@ -1,6 +1,5 @@
============
Cryptography
============
Basic Cryptography Module
=========================
.. warning::
@@ -51,18 +50,10 @@ substitutions at different times in the message.
.. autofunction:: decipher_shift
.. autofunction:: encipher_rot13
.. autofunction:: decipher_rot13
.. autofunction:: encipher_affine
.. autofunction:: decipher_affine
.. autofunction:: encipher_atbash
.. autofunction:: decipher_atbash
.. autofunction:: encipher_substitution
.. autofunction:: encipher_vigenere
@@ -141,8 +132,4 @@ substitutions at different times in the message.
.. autofunction:: encipher_gm
.. autofunction:: decipher_gm
.. autofunction:: encipher_railfence
.. autofunction:: decipher_railfence
.. autofunction:: decipher_gm
+2 -3
View File
@@ -1,6 +1,5 @@
=====================
Differential Geometry
=====================
Differential Geometry Module
============================
.. module:: sympy.diffgeom
-96
View File
@@ -1,96 +0,0 @@
========
Discrete
========
The ``discrete`` module in SymPy implements methods to compute discrete
transforms and convolutions of finite sequences.
.. automodule:: sympy.discrete
Since the discrete transforms can be used to reduce the computational complexity
of the discrete convolutions, the ``convolutions`` module makes use of the
``transforms`` module for efficient computation (notable for long input sequences).
Transforms
----------
.. module:: sympy.discrete.transforms
This section lists the methods which implement the basic transforms
for discrete sequences.
Fast Fourier Transform
^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: fft
.. autofunction:: ifft
Number Theoretic Transform
^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: ntt
.. autofunction:: intt
Fast Walsh Hadamard Transform
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: fwht
.. autofunction:: ifwht
Möbius Transform
^^^^^^^^^^^^^^^^
.. autofunction:: mobius_transform
.. autofunction:: inverse_mobius_transform
Convolutions
------------
.. module:: sympy.discrete.convolutions
This section lists the methods which implement the basic convolutions
for discrete sequences.
Convolution
^^^^^^^^^^^
This is a general method for calculating the convolution of discrete
sequences, which internally calls one of the methods ``convolution_fft``,
``convolution_ntt``, ``convolution_fwht``, or ``convolution_subset``.
.. autofunction:: convolution
Convolution using Fast Fourier Transform
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: convolution_fft
Convolution using Number Theoretic Transform
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: convolution_ntt
Convolution using Fast Walsh Hadamard Transform
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: convolution_fwht
Subset Convolution
^^^^^^^^^^^^^^^^^^
.. autofunction:: convolution_subset
Covering Product
^^^^^^^^^^^^^^^^
.. autofunction:: covering_product
Intersecting Product
^^^^^^^^^^^^^^^^^^^^
.. autofunction:: intersecting_product
+3 -4
View File
@@ -1,7 +1,6 @@
.. _evalf-label:
====================
Numerical Evaluation
Numerical evaluation
====================
Basics
@@ -70,7 +69,7 @@ This shows digits 999,951 through 1,000,000 of pi:
High-precision calculations can be slow. It is recommended (but entirely
optional) to install gmpy (https://code.google.com/p/gmpy/), which will
optional) to install gmpy (http://code.google.com/p/gmpy/), which will
significantly speed up computations such as the one above.
Floating-point numbers
@@ -287,7 +286,7 @@ Oscillatory quadrature requires an integrand containing a factor cos(ax+b) or
sin(ax+b). Note that many other oscillatory integrals can be transformed to
this form with a change of variables:
>>> init_printing(use_unicode=False, wrap_line=False)
>>> init_printing(use_unicode=False, wrap_line=False, no_global=True)
>>> intgrl = Integral(sin(1/x), (x, 0, 1)).transform(x, 1/x)
>>> intgrl
oo
+1 -18
View File
@@ -66,36 +66,19 @@ fibonacci
.. autoclass:: sympy.functions.combinatorial.numbers.fibonacci
:members:
tribonacci
----------
.. autoclass:: sympy.functions.combinatorial.numbers.tribonacci
:members:
harmonic
--------
.. autoclass:: sympy.functions.combinatorial.numbers.harmonic
:members:
lucas
-----
.. autoclass:: sympy.functions.combinatorial.numbers.lucas
:members:
genocchi
--------
.. autoclass:: sympy.functions.combinatorial.numbers.genocchi
:members:
partition
---------
.. autoclass:: sympy.functions.combinatorial.numbers.partition
:members:
MultiFactorial
--------------
+2 -5
View File
@@ -66,11 +66,8 @@ principal_branch
sympy.functions.elementary.trigonometric
========================================
.. _trionometric functions:
Trigonometric Functions
========================
Trionometric Functions
======================
sin
---
+2 -3
View File
@@ -1,8 +1,7 @@
.. _functions:
=========
Functions
=========
Functions Module
****************
.. module:: sympy.functions
+4 -4
View File
@@ -1,6 +1,6 @@
========
Geometry
========
===============
Geometry Module
===============
Introduction
@@ -140,7 +140,7 @@ References
.. [WikiPappus] "Pappus's Hexagon Theorem" Wikipedia, the Free Encyclopedia.
Web. 26 Apr. 2013.
<https://en.wikipedia.org/wiki/Pappus's_hexagon_theorem>
<http://en.wikipedia.org/wiki/Pappus's_hexagon_theorem>
Miscellaneous Notes
-------------------
+1 -1
View File
@@ -36,7 +36,7 @@ Here `D` is the Differential Operator and `L` is called the annihilator
of the function.
A unique holonomic function can be defined from the annihilator and a set of
initial conditions.
initial conditons.
For instance:
.. math::
+1 -1
View File
@@ -1,7 +1,7 @@
Converting other representations to holonomic
=============================================
.. currentmodule:: sympy.holonomic.holonomic
.. module:: sympy.holonomic.holonomic
Converting hypergeometric functions
-----------------------------------
+3 -3
View File
@@ -1,8 +1,8 @@
.. _holonomic-docs:
=========
Holonomic
=========
===================
Holonomic Functions
===================
.. automodule:: sympy.holonomic
+1 -1
View File
@@ -29,7 +29,7 @@ a holonomic functions.
>>> p * q
HolonomicFunction((2) + (-2)*Dx + (1)*Dx**2, x, 0, [0, 1])
.. currentmodule:: sympy.holonomic.holonomic
.. module:: sympy.holonomic.holonomic
Integration and Differentiation
-------------------------------
+1 -1
View File
@@ -1,7 +1,7 @@
Representation of holonomic functions in SymPy
==============================================
.. currentmodule:: sympy.holonomic.holonomic
.. module:: sympy.holonomic.holonomic
Class :class:`DifferentialOperator` is used to represent the annihilator
but we create differential operators easily using the function
+3 -3
View File
@@ -1,4 +1,4 @@
.. currentmodule:: sympy.holonomic.holonomic
.. module:: sympy.holonomic.holonomic
Uses and Current limitations
============================
@@ -44,10 +44,10 @@ which initial conditions for the integrand are stored. Sometimes this gives an a
For instance:
>>> expr_to_holonomic(sin(x)).integrate(x).to_expr()
1 - cos(x)
-cos(x) + 1
>>> sin(x).integrate(x)
-cos(x)
The indefinite integral of `\sin(x)` is `-\cos(x)`. But the output is `-\cos(x) + 1`
which is `\int_{0}^{x} sin(x)dx`. Although both are considered correct but `-\cos(x)`
is simpler.
is simpler.
+22 -24
View File
@@ -16,49 +16,47 @@ access any SymPy module, or use the list below:
.. toctree::
:maxdepth: 2
algebras.rst
assumptions/index.rst
calculus/index.rst
categories.rst
codegen.rst
combinatorics/index.rst
concrete.rst
core.rst
combinatorics/index.rst
ntheory.rst
crypto.rst
diffgeom.rst
solvers/diophantine.rst
discrete.rst
concrete.rst
evalf.rst
codegen.rst
numeric-computation.rst
functions/index.rst
geometry/index.rst
holonomic/index.rst
simplify/hyperexpand.rst
solvers/inequalities.rst
integrals/integrals.rst
liealgebras/index.rst
logic.rst
matrices/index.rst
ntheory.rst
numeric-computation.rst
evalf.rst
solvers/ode.rst
parsing.rst
solvers/pde.rst
physics/index.rst
plotting.rst
polys/index.rst
printing.rst
plotting.rst
assumptions/index.rst
rewriting.rst
series/index.rst
sets.rst
simplify/simplify.rst
solvers/solvers.rst
solvers/solveset.rst
simplify/hyperexpand.rst
stats.rst
solvers/ode.rst
solvers/pde.rst
solvers/solvers.rst
solvers/diophantine.rst
solvers/inequalities.rst
solvers/solveset.rst
tensor/index.rst
rewriting.rst
utilities/index.rst
parsing.rst
calculus/index.rst
physics/index.rst
categories.rst
diffgeom.rst
vector/index.rst
Contributions to Docs
Contributions to docs
---------------------
All contributions are welcome. If you'd like to improve something, look into
+1 -1
View File
@@ -161,7 +161,7 @@ is satisfies `G(\operatorname{Exp}(2 \pi i)z) = G(z)` for all `z \in \mathcal{S}
be used to exploit the information. This is done transparently by the
integration code.
.. [BlogPost] https://nessgrh.wordpress.com/2011/07/07/tricky-branch-cuts/
.. [BlogPost] http://nessgrh.wordpress.com/2011/07/07/tricky-branch-cuts/
The G-Function Integration Theorems
***********************************
+9 -11
View File
@@ -1,6 +1,5 @@
=========
Integrals
=========
Symbolic Integrals
==================
.. module:: sympy.integrals
@@ -16,7 +15,7 @@ Examples
SymPy can integrate a vast array of functions. It can integrate polynomial functions::
>>> from sympy import *
>>> init_printing(use_unicode=False, wrap_line=False)
>>> init_printing(use_unicode=False, wrap_line=False, no_global=True)
>>> x = Symbol('x')
>>> integrate(x**2 + x + 1, x)
3 2
@@ -26,10 +25,10 @@ SymPy can integrate a vast array of functions. It can integrate polynomial funct
Rational functions::
>>> integrate(x/(x**2+2*x+1), x)
1
log(x + 1) + -----
x + 1
>>> integrate(x/(x**2+2*x+1), x)
1
log(x + 1) + -----
x + 1
Exponential-polynomial functions. These multiplicative combinations of polynomials and the functions ``exp``, ``cos`` and ``sin`` can be integrated by hand using repeated integration by parts, which is an extremely tedious process. Happily, SymPy will deal with these integrals.
@@ -128,8 +127,6 @@ any order and any precision:
.. autofunction:: sympy.integrals.quadrature.gauss_jacobi
.. autofunction:: sympy.integrals.quadrature.gauss_lobatto
Integration over Polytopes
==========================
@@ -173,7 +170,7 @@ For 2D Polygons
Single Polynomial::
>>> from sympy.integrals.intpoly import *
>>> init_printing(use_unicode=False, wrap_line=False)
>>> init_printing(use_unicode=False, wrap_line=False, no_global=True)
>>> polytope_integrate(Polygon((0, 0), (0, 1), (1, 0)), x)
1/6
>>> polytope_integrate(Polygon((0, 0), (0, 1), (1, 0)), x + x*y + y**2)
@@ -232,3 +229,4 @@ API reference
-------------
.. autofunction:: sympy.integrals.intpoly.polytope_integrate
+3 -3
View File
@@ -1,6 +1,6 @@
===========
Lie Algebra
===========
==================
Lie Algebra Module
==================
.. automodule:: sympy.liealgebras
+4 -5
View File
@@ -1,6 +1,5 @@
=====
Logic
=====
Logic Module
===============
.. module:: sympy.logic
@@ -47,7 +46,7 @@ from their truth tables-
.. autofunction:: sympy.logic.boolalg.POSform
Boolean functions
-----------------
-----------------------
.. autoclass:: sympy.logic.boolalg.BooleanTrue
@@ -95,7 +94,7 @@ simplest forms.
Inference
---------
.. module:: sympy.logic.inference
.. module: sympy.logic.inference
This module implements some inference routines in propositional logic.
-10
View File
@@ -1,10 +0,0 @@
Common Matrices
===============
.. module:: sympy.matrices.common
MatrixCommon Class Reference
----------------------------
.. autoclass:: MatrixCommon
:members:
:inherited-members:
+1 -5
View File
@@ -9,7 +9,7 @@ The Matrix expression module allows users to write down statements like
>>> X = MatrixSymbol('X', 3, 3)
>>> Y = MatrixSymbol('Y', 3, 3)
>>> (X.T*X).I*Y
X**(-1)*X.T**(-1)*Y
X^-1*X.T^-1*Y
>>> Matrix(X)
Matrix([
@@ -34,10 +34,6 @@ Matrix Expressions Core Reference
:members:
.. autoclass:: MatPow
:members:
.. autoclass:: HadamardProduct
:members:
.. autoclass:: HadamardPower
:members:
.. autoclass:: Inverse
:members:
.. autoclass:: Transpose
-1
View File
@@ -12,7 +12,6 @@ Contents:
:maxdepth: 2
matrices.rst
common.rst
dense.rst
sparse.rst
immutablematrices.rst
+3 -51
View File
@@ -10,7 +10,7 @@ The linear algebra module is designed to be as simple as possible. First, we
import and declare our first ``Matrix`` object:
>>> from sympy.interactive.printing import init_printing
>>> init_printing(use_unicode=False, wrap_line=False)
>>> init_printing(use_unicode=False, wrap_line=False, no_global=True)
>>> from sympy.matrices import Matrix, eye, zeros, ones, diag, GramSchmidt
>>> M = Matrix([[1,0,0], [0,0,0]]); M
[1 0 0]
@@ -325,31 +325,6 @@ but we can also apply functions to our matrix entries using ``applyfunc()``. Her
[ ]
[0 0 2]
If you want to extract a common factor from a matrix you can do so by
applying ``gcd`` to the data of the matrix:
>>> from sympy.abc import x, y
>>> from sympy import gcd
>>> m = Matrix([[x, y], [1, x*y]]).inv(); m
[ -x*y y ]
[---------- ----------]
[ 2 2 ]
[- x *y + y - x *y + y]
[ ]
[ 1 -x ]
[---------- ----------]
[ 2 2 ]
[- x *y + y - x *y + y]
>>> gcd(tuple(_))
1
----------
2
- x *y + y
>>> m/_
[-x*y y ]
[ ]
[ 1 -x]
One more useful matrix-wide entry application function is the substitution function. Let's declare a matrix with symbolic entries then substitute a value. Remember we can substitute anything - even another symbol!:
>>> from sympy import Symbol
@@ -523,31 +498,6 @@ So there is quite a bit that can be done with the module including eigenvalues,
eigenvectors, nullspace calculation, cofactor expansion tools, and so on. From
here one might want to look over the ``matrices.py`` file for all functionality.
MatrixDeterminant Class Reference
---------------------------------
.. autoclass:: MatrixDeterminant
:members:
MatrixReductions Class Reference
--------------------------------
.. autoclass:: MatrixReductions
:members:
MatrixSubspaces Class Reference
-------------------------------
.. autoclass:: MatrixSubspaces
:members:
MatrixEigen Class Reference
---------------------------
.. autoclass:: MatrixEigen
:members:
MatrixCalculus Class Reference
------------------------------
.. autoclass:: MatrixCalculus
:members:
MatrixBase Class Reference
--------------------------
.. autoclass:: MatrixBase
@@ -566,6 +516,8 @@ Matrix Exceptions Reference
Matrix Functions Reference
--------------------------
.. autofunction:: classof
.. autofunction:: sympy.matrices.dense.matrix_multiply_elementwise
.. autofunction:: sympy.matrices.dense.zeros
+7 -46
View File
@@ -1,6 +1,5 @@
=============
Number Theory
=============
====================
.. module:: sympy.ntheory.generate
@@ -50,8 +49,6 @@ Ntheory Functions Reference
.. autofunction:: factorint
.. autofunction:: factorrat
.. autofunction:: primefactors
.. autofunction:: divisors
@@ -66,41 +63,21 @@ Ntheory Functions Reference
.. autofunction:: antidivisor_count
.. autoclass:: totient
:members:
.. autofunction:: totient
.. autoclass:: reduced_totient
:members:
.. autofunction:: reduced_totient
.. autoclass:: divisor_sigma
:members:
.. autofunction:: divisor_sigma
.. autoclass:: udivisor_sigma
:members:
.. autofunction:: udivisor_sigma
.. autofunction:: core
.. autofunction:: digits
.. autoclass:: primenu
:members:
.. autofunction:: primenu
.. autoclass:: primeomega
:members:
.. autofunction:: mersenne_prime_exponent
.. autofunction:: is_perfect
.. autofunction:: is_mersenne_prime
.. autofunction:: abundance
.. autofunction:: is_abundant
.. autofunction:: is_deficient
.. autofunction:: is_amicable
.. autofunction:: primeomega
.. module:: sympy.ntheory.modular
@@ -130,18 +107,8 @@ Ntheory Functions Reference
.. module:: sympy.ntheory.primetest
.. autofunction:: is_euler_pseudoprime
.. autofunction:: is_square
.. autofunction:: mr
.. autofunction:: is_lucas_prp
.. autofunction:: is_strong_lucas_prp
.. autofunction:: is_extra_strong_lucas_prp
.. autofunction:: isprime
.. module:: sympy.ntheory.residue_ntheory
@@ -154,8 +121,6 @@ Ntheory Functions Reference
.. autofunction:: sqrt_mod
.. autofunction:: sqrt_mod_iter
.. autofunction:: quadratic_residues
.. autofunction:: nthroot_mod
@@ -179,7 +144,3 @@ Ntheory Functions Reference
.. module:: sympy.ntheory.egyptian_fraction
.. autofunction:: egyptian_fraction
.. module:: sympy.ntheory.bbp_pi
.. autofunction:: pi_hex_digits
+2 -2
View File
@@ -66,8 +66,8 @@ powerful vectorized ufuncs that are backed by compiled C code.
>>> import numpy
>>> data = numpy.linspace(1, 10, 10000)
>>> f(data)
[ 0.84147098 0.84119981 0.84092844 ... -0.05426074 -0.05433146
-0.05440211]
[ 0.84147098 0.84119981 0.84092844 ..., -0.05426074 -0.05433146
-0.05440211]
If you have array-based data this can confer a considerable speedup, on the
order of 10 nano-seconds per element. Unfortunately numpy incurs some start-up
+2 -24
View File
@@ -1,6 +1,5 @@
=======
Parsing
=======
Parsing input
=============
Parsing Functions Reference
---------------------------
@@ -91,27 +90,6 @@ change between releases, and become stricter, more relaxed, or some mix.
.. autoclass:: sympy.parsing.latex.LaTeXParsingError
SymPy Expression Reference
--------------------------
.. module:: sympy.parsing.sym_expr
.. autoclass:: SymPyExpression
:members:
`Fortran` Parsing Reference
---------------------------------
.. module:: sympy.parsing.fortran.fortran_parser
.. autoclass:: ASR2PyVisitor
:members:
.. autofunction:: call_visitor
.. autofunction:: src_to_sympy
Runtime Installation
--------------------
@@ -2,268 +2,113 @@
Solving Beam Bending Problems using Singularity Functions
===========================================================
To make this document easier to read, enable pretty printing:
To make this document easier to read, we are going to enable pretty printing.
.. plot::
:context: reset
:format: doctest
:include-source: True
>>> from sympy import *
>>> x, y, z = symbols('x y z')
>>> init_printing(use_unicode=True, wrap_line=False)
>>> from sympy import *
>>> x, y, z = symbols('x y z')
>>> init_printing(use_unicode=True, wrap_line=False)
Beam
====
A planar beam is a structural element that is capable of withstanding load
through resistance to internal shear and bending. Beams are characterized by
their length, constraints, cross-sectional second moment of area, and elastic
modulus. In SymPy, 2D beam objects are constructed by specifying the following
properties:
A Beam is a structural element that is capable of withstanding load
primarily by resisting against bending. Beams are characterized by
their second moment of area, their length and their elastic modulus.
In Sympy, we can construct a 2D beam objects with the following properties :
- Length
- Elastic Modulus
- Second Moment of Area
- Variable : A symbol representing the location along the beam's length. By
default, this is set to ``Symbol(x)``.
- Variable : A symbol that can be used as a variable along the length. By default,
this is set to ``Symbol(x)``.
- Boundary Conditions
- bc_slope : Boundary conditions for slope.
- bc_deflection : Boundary conditions for deflection.
- bc_slope : Boundary conditions for slope.
- bc_deflection : Boundary conditions for deflection.
- Load Distribution
Once the above are specified, the following methods are used to compute useful
information about the loaded beam:
We have following methods under the beam class:
- apply_load
- solve_for_reaction_loads
- shear_force
- bending_moment
- slope
- deflection
- ``solve_for_reaction_loads()``
- ``shear_force()``
- ``bending_moment()``
- ``slope()``
Examples
========
Below are examples of a variety two dimensional beam bending problems.
Let us solve some beam bending problems using this module :
Example 1
---------
A cantilever beam 9 meters in length has a distributed constant load of 8 kN/m
applied downward from the fixed end over a 5 meter distance. A counterclockwise
moment of 50 kN-m is applied 5 meters from the fixed end. Lastly, a downward
point load of 12 kN is applied at the free end of the beam.
::
y
^
|
\\\\|
\\\\| 8 kN/m
\\\\|_________________
\\\\|| | | | | | | | | 12 kN
\\\\|V V V V V V V V V |
\\\\|________________|_______________V
\\\\| | |
\\\\o - - - - - - - -⭯ 50 kN-m - - - | - - -> x
\\\\|________________|_______________|
\\\\| :
\\\\|----------------|---------------|
5.0 m 4.0 m
A beam of length 9 meters is having a fixed support at the start.
A distributed constant load of 8 kN/m is applied downward from the starting
point till 5 meters away from the start. A clockwise moment of 50 kN-m is
applied at 5 meters away from the start of the beam. A downward point load
of 12 kN is applied at the end.
.. note::
The user is free to choose their own sign convention. In this case the
upward forces and counterclockwise bending moment being positive.
Since a user is free to choose its own sign convention we are considering
the upward forces and clockwise bending moment being positive.
The beam must be initialized with the length, modulus of elasticity, and the
second moment of area. These quantities can be symbols or numbers.
.. plot::
:context:
:format: doctest
:include-source: True
>>> from sympy.physics.continuum_mechanics.beam import Beam
>>> E, I = symbols('E, I')
>>> b = Beam(9, E, I)
The three loads are applied to the beam using the ``apply_load()`` method. This
method supports point forces, point moments, and polynomial distributed loads
of any order, i.e. :math:`c, cx, cx^2, cx^3, \ldots``.
The 12 kN point load is in the negative direction, at the location of 9 meters,
and the polynomial order is specified as -1:
.. plot::
:context:
:format: doctest
:include-source: True
>>> b.apply_load(-12, 9, -1)
The ``load`` attribute can then be used to access the loading function in
singularity function form:
.. plot::
:context:
:format: doctest
:include-source: True
>>> b.load
-1
-12⋅<x - 9>
Similarly, the positive moment can be applied with a polynomial order -2:
.. plot::
:context:
:format: doctest
:include-source: True
>>> b.apply_load(50, 5, -2)
The distributed load is of order 0 and spans x=0 to x=5:
.. plot::
:context:
:format: doctest
:include-source: True
>>> b.apply_load(-8, 0, 0, end=5)
The fixed end imposes two boundary conditions: 1) no vertical deflection and 2)
no rotation. These are specified by appending tuples of x values and the
corresponding deflection or slope values:
.. plot::
:context:
:format: doctest
:include-source: True
>>> b.bc_deflection.append((0, 0))
>>> b.bc_slope.append((0, 0))
These boundary conditions introduce an unknown reaction force and moment which
need to be applied to the beam to maintain static equilibrium:
.. plot::
:context:
:format: doctest
:include-source: True
>>> R, M = symbols('R, M')
>>> b.apply_load(R, 0, -1)
>>> b.apply_load(M, 0, -2)
>>> b.load
-2 -1 0 -2 0 -1
M⋅<x> + R⋅<x> - 8⋅<x> + 50⋅<x - 5> + 8⋅<x - 5> - 12⋅<x - 9>
These two variables can be solved for in terms of the applied loads and the
final loading can be displayed:
.. plot::
:context:
:format: doctest
:include-source: True
>>> b.solve_for_reaction_loads(R, M)
>>> b.reaction_loads
{M: -258, R: 52}
>>> b.load
-2 -1 0 -2 0 -1
- 258⋅<x> + 52⋅<x> - 8⋅<x> + 50⋅<x - 5> + 8⋅<x - 5> - 12⋅<x - 9>
At this point, the beam is fully defined and the internal shear and bending
moments are calculated:
.. plot::
:context:
:format: doctest
:include-source: True
>>> b.shear_force()
-1 0 1 -1 1 0
- 258⋅<x> + 52⋅<x> - 8⋅<x> + 50⋅<x - 5> + 8⋅<x - 5> - 12⋅<x - 9>
>>> b.bending_moment()
0 1 2 0 2 1
- 258⋅<x> + 52⋅<x> - 4⋅<x> + 50⋅<x - 5> + 4⋅<x - 5> - 12⋅<x - 9>
These can be visualized by calling the respective plot methods:
.. plot::
:context:
:format: doctest
:include-source: True
>>> b.plot_shear_force() # doctest: +SKIP
>>> b.plot_bending_moment() # doctest: +SKIP
The beam will deform under load and the slope and deflection can be determined
with:
.. plot::
:context: close-figs
:format: doctest
:include-source: True
>>> b.slope()
3 3
1 2 4⋅<x> 1 4⋅<x - 5> 2
- 258⋅<x> + 26⋅<x> - ────── + 50⋅<x - 5> + ────────── - 6⋅<x - 9>
3 3
─────────────────────────────────────────────────────────────────────
E⋅I
>>> b.deflection()
3 4 4
2 26⋅<x> <x> 2 <x - 5> 3
- 129⋅<x> + ─────── - ──── + 25⋅<x - 5> + ──────── - 2⋅<x - 9>
3 3 3
─────────────────────────────────────────────────────────────────
E⋅I
The slope and deflection of the beam can be plotted so long as numbers are
provided for the modulus and second moment:
.. plot::
:context: close-figs
:format: doctest
:include-source: True
>>> b.plot_slope(subs={E: 20E9, I: 3.25E-6}) # doctest: +SKIP
>>> b.plot_deflection(subs={E: 20E9, I: 3.25E-6}) # doctest: +SKIP
All of the plots can be shown in one figure with:
.. plot::
:context: close-figs
:format: doctest
:include-source: True
>>> b.plot_loading_results(subs={E: 20E9, I: 3.25E-6}) # doctest: +SKIP
>>> from sympy.physics.continuum_mechanics.beam import Beam
>>> from sympy import symbols
>>> E, I = symbols('E, I')
>>> R1, M1 = symbols('R1, M1')
>>> b = Beam(9, E, I)
>>> b.apply_load(R1, 0, -1)
>>> b.apply_load(M1, 0, -2)
>>> b.apply_load(-8, 0, 0, end=5)
>>> b.apply_load(50, 5, -2)
>>> b.apply_load(-12, 9, -1)
>>> b.bc_slope.append((0, 0))
>>> b.bc_deflection.append((0, 0))
>>> b.solve_for_reaction_loads(R1, M1)
>>> b.reaction_loads
{M₁: -258, R₁: 52}
>>> b.load
-2 -1 0 -2 0 -1
- 258⋅<x> + 52⋅<x> - 8⋅<x> + 50⋅<x - 5> + 8⋅<x - 5> - 12⋅<x - 9>
>>> b.shear_force()
-1 0 1 -1 1 0
- 258⋅<x> + 52⋅<x> - 8⋅<x> + 50⋅<x - 5> + 8⋅<x - 5> - 12⋅<x - 9>
>>> b.bending_moment()
0 1 2 0 2 1
- 258⋅<x> + 52⋅<x> - 4⋅<x> + 50⋅<x - 5> + 4⋅<x - 5> - 12⋅<x - 9>
>>> b.slope()
3 3
1 2 4⋅<x> 1 4⋅<x - 5> 2
- 258⋅<x> + 26⋅<x> - ────── + 50⋅<x - 5> + ────────── - 6⋅<x - 9>
3 3
─────────────────────────────────────────────────────────────────────
E⋅I
>>> b.deflection()
3 4 4
2 26⋅<x> <x> 2 <x - 5> 3
- 129⋅<x> + ─────── - ──── + 25⋅<x - 5> + ──────── - 2⋅<x - 9>
3 3 3
─────────────────────────────────────────────────────────────────
E⋅I
Example 2
---------
There is a beam of length 30 meters. A moment of magnitude 120 Nm is
applied in the clockwise direction at the end of the beam. A point load
applied in the clockwise direction at the end of the beam. A pointload
of magnitude 8 N is applied from the top of the beam at the starting
point. There are two simple supports below the beam. One at the end
and another one at a distance of 10 meters from the start. The
deflection is restricted at both the supports.
::
|| 8 N ⭯ 120 Nm
\/______________________________________________|
|_______________________________________________|
/\ /\
|------------|---------------------------------|
10 m 20 m
.. note::
Using the sign convention of upward forces and counterclockwise moment
Using the sign convention of upward forces and clockwise moment
being positive.
>>> from sympy.physics.continuum_mechanics.beam import Beam
@@ -282,50 +127,38 @@ deflection is restricted at both the supports.
{R₁: 6, R₂: 2}
>>> b.load
-1 -1 -2 -1
- 8⋅<x> + 6⋅<x - 10> + 120⋅<x - 30> + 2⋅<x - 30>
- 8⋅<x> + 6⋅<x - 10> + 120⋅<x - 30> + 2⋅<x - 30>
>>> b.shear_force()
0 0 -1 0
- 8⋅<x> + 6⋅<x - 10> + 120⋅<x - 30> + 2⋅<x - 30>
- 8⋅<x> + 6⋅<x - 10> + 120⋅<x - 30> + 2⋅<x - 30>
>>> b.bending_moment()
1 1 0 1
- 8⋅<x> + 6⋅<x - 10> + 120⋅<x - 30> + 2⋅<x - 30>
- 8⋅<x> + 6⋅<x - 10> + 120⋅<x - 30> + 2⋅<x - 30>
>>> b.slope()
2 2 1 2 4000
- 4⋅<x> + 3⋅<x - 10> + 120⋅<x - 30> + <x - 30> + ────
3
3
─────────────────────────────────────────────────────────
E⋅I
E⋅I
>>> b.deflection()
3 3
4000⋅x 4⋅<x> 3 2 <x - 30>
3 3
4000⋅x 4⋅<x> 3 2 <x - 30>
────── - ────── + <x - 10> + 60⋅<x - 30> + ───────── - 12000
3 3 3
3 3 3
──────────────────────────────────────────────────────────────
E⋅I
E⋅I
Example 3
---------
A beam of length 6 meters is having a roller support at the start and a hinged
support at the end. A counterclockwise moment of 1.5 kN-m is applied at the mid
of the beam. A constant distributed load of 3 kN/m and a ramp load of 1 kN/m is
applied from the mid till the end of the beam.
::
ramp load = 1 KN/m
constant load = 3 KN/m
|------------------------|
⭯ 1.5 KN-m
______________________|________________________
|_______________________________________________|
o | /\
|----------------------|-----------------------|
3.0 m 3.0 m
A beam of length 6 meters is having a roller support at the start and a
hinged support at the end. A clockwise moment of 1.5 kN-m is applied at the mid
of the beam. A constant distributed load of 3 kN/m and a ramp load of 1 kN/m
is applied from the mid til the end of the beam.
.. note::
Using the sign convention of upward forces and counterclockwise moment
Using the sign convention of upward forces and clockwise moment
being positive.
>>> from sympy.physics.continuum_mechanics.beam import Beam
@@ -345,540 +178,28 @@ applied from the mid till the end of the beam.
{R₁: 2.75, R₂: 10.75}
>>> b.load
-1 -2 0 1 -1
2.75⋅<x> + 1.5⋅<x - 3> - 3⋅<x - 3> - <x - 3> + 10.75⋅<x - 6>
2.75⋅<x> + 1.5⋅<x - 3> - 3⋅<x - 3> - <x - 3> + 10.75⋅<x - 6>
>>> b.shear_force()
2
2
0 -1 1 <x - 3> 0
2.75⋅<x> + 1.5⋅<x - 3> - 3⋅<x - 3> - ──────── + 10.75⋅<x - 6>
2
2.75⋅<x> + 1.5⋅<x - 3> - 3⋅<x - 3> - ──────── + 10.75⋅<x - 6>
2
>>> b.bending_moment()
2 3
2 3
1 0 3⋅<x - 3> <x - 3> 1
2.75⋅<x> + 1.5⋅<x - 3> - ────────── - ──────── + 10.75⋅<x - 6>
2 6
2.75⋅<x> + 1.5⋅<x - 3> - ────────── - ──────── + 10.75⋅<x - 6>
2 6
>>> b.slope()
3 4
2 1 <x - 3> <x - 3> 2
3 4
2 1 <x - 3> <x - 3> 2
1.375⋅<x> + 1.5⋅<x - 3> - ──────── - ──────── + 5.375⋅<x - 6> - 15.6
2 24
2 24
───────────────────────────────────────────────────────────────────────
E⋅I
E⋅I
>>> b.deflection()
4 5
4 5
3 2 <x - 3> <x - 3> 3
-15.6⋅x + 0.458333333333333⋅<x> + 0.75⋅<x - 3> - ──────── - ──────── + 1.79166666666667⋅<x - 6>
8 120
-15.6⋅x + 0.458333333333333⋅<x> + 0.75⋅<x - 3> - ──────── - ──────── + 1.79166666666667⋅<x - 6>
8 120
──────────────────────────────────────────────────────────────────────────────────────────────────
E⋅I
Example 4
---------
An overhanging beam of length 8 meters is pinned at 1 meter from starting point
and supported by a roller 1 meter before the other end. It is subjected
to a distributed constant load of 10 KN/m from the starting point till
2 meters away from it. Two point loads of 20KN and 8KN are applied at
5 meters and 7.5 meters away from the starting point respectively.
::
---> x
|
v y
10 KN/m
_____________ 20 KN 8 KN
| | | | | | | | |
V V V V V V V V V
_______________________________________________
|_______________________________________________|
/\ O
|-----|------|-----------------|----------|--|--|
1m 1m 3m 2m .5m .5m
.. code:: pycon
>>> from sympy.physics.continuum_mechanics.beam import Beam
>>> from sympy import symbols
>>> E,I,M,V = symbols('E I M V')
>>> b = Beam(8, E, I)
>>> E,I,R1,R2 = symbols('E I R1 R2')
>>> b.apply_load(R1, 1, -1)
>>> b.apply_load(R2, 7, -1)
>>> b.apply_load(10, 0, 0, end=2)
>>> b.apply_load(20, 5, -1)
>>> b.apply_load(8, 7.5, -1)
>>> b.solve_for_reaction_loads(R1, R2)
>>> b.reaction_loads
{R₁: -26.0, R₂: -22.0}
>>> b.load
0 -1 0 -1 -1 -1
10⋅<x> - 26.0⋅<x - 1> - 10⋅<x - 2> + 20⋅<x - 5> - 22.0⋅<x - 7> + 8⋅<x - 7.5>
>>> b.shear_force()
1 0 1 0 0 0
10⋅<x> - 26.0⋅<x - 1> - 10⋅<x - 2> + 20⋅<x - 5> - 22.0⋅<x - 7> + 8⋅<x - 7.5>
>>> b.bending_moment()
2 1 2 1 1 1
5⋅<x> - 26.0⋅<x - 1> - 5⋅<x - 2> + 20⋅<x - 5> - 22.0⋅<x - 7> + 8⋅<x - 7.5>
>>> b.bc_deflection = [(1, 0), (7, 0)]
>>> b.slope()
3 3
5⋅<x> 2 5⋅<x - 2> 2 2 2
────── - 13.0⋅<x - 1> - ────────── + 10⋅<x - 5> - 11.0⋅<x - 7> + 4⋅<x - 7.5> + 28.2916666666667
3 3
───────────────────────────────────────────────────────────────────────────────────────────────────
E⋅I
>>> b.deflection()
4 4 3 3
5⋅<x> 3 5⋅<x - 2> 10⋅<x - 5> 3 4⋅<x - 7.5>
28.2916666666667⋅x + ────── - 4.33333333333333⋅<x - 1> - ────────── + ─────────── - 3.66666666666667⋅<x - 7> + ──────────── - 28.7083333333333
12 12 3 3
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
E⋅I
Example 5
---------
A cantilever beam of length 6 meters is under downward distributed constant
load with magnitude of 4.0 KN/m from starting point till 2 meters away
from it. A ramp load of 1 kN/m applied from the mid till the end of
the beam. A point load of 12KN is also applied in same direction 4 meters
away from start.
::
---> x .
| . |
v y 12 KN . | |
| . | | |
V . | | | |
\\\\| 4 KN/m . | | | | |
\\\\|___________ . 1 KN/m | |
\\\\|| | | | | | . V V V V V V V
\\\\|V V V V V V |---------------|
\\\\|________________________________
\\\\|________________________________|
\\\\| : : :
\\\\|----------|-----|----|----------|
2.0 m 1m 1m 2.0 m
.. code:: pycon
>>> from sympy.physics.continuum_mechanics.beam import Beam
>>> from sympy import symbols
>>> E,I,M,V = symbols('E I M V')
>>> b = Beam(6, E, I)
>>> b.apply_load(V, 0, -1)
>>> b.apply_load(M, 0, -2)
>>> b.apply_load(4, 0, 0, end=2)
>>> b.apply_load(12, 4, -1)
>>> b.apply_load(1, 3, 1, end=6)
>>> b.solve_for_reaction_loads(V, M)
>>> b.reaction_loads
{M: 157/2, V: -49/2}
>>> b.load
-2 -1
157⋅<x> 49⋅<x> 0 0 1 -1 0 1
───────── - ──────── + 4⋅<x> - 4⋅<x - 2> + <x - 3> + 12⋅<x - 4> - 3⋅<x - 6> - <x - 6>
2 2
>>> b.shear_force()
-1 0 2 2
157⋅<x> 49⋅<x> 1 1 <x - 3> 0 1 <x - 6>
───────── - ─────── + 4⋅<x> - 4⋅<x - 2> + ──────── + 12⋅<x - 4> - 3⋅<x - 6> - ────────
2 2 2 2
>>> b.bending_moment()
0 1 3 2 3
157⋅<x> 49⋅<x> 2 2 <x - 3> 1 3⋅<x - 6> <x - 6>
──────── - ─────── + 2⋅<x> - 2⋅<x - 2> + ──────── + 12⋅<x - 4> - ────────── - ────────
2 2 6 2 6
>>> b.bc_deflection = [(0, 0)]
>>> b.bc_slope = [(0, 0)]
>>> b.slope()
1 2 3 3 4 3 4
157⋅<x> 49⋅<x> 2⋅<x> 2⋅<x - 2> <x - 3> 2 <x - 6> <x - 6>
──────── - ─────── + ────── - ────────── + ──────── + 6⋅<x - 4> - ──────── - ────────
2 4 3 3 24 2 24
──────────────────────────────────────────────────────────────────────────────────────
E⋅I
>>> b.deflection()
2 3 4 4 5 4 5
157⋅<x> 49⋅<x> <x> <x - 2> <x - 3> 3 <x - 6> <x - 6>
──────── - ─────── + ──── - ──────── + ──────── + 2⋅<x - 4> - ──────── - ────────
4 12 6 6 120 8 120
──────────────────────────────────────────────────────────────────────────────────
E⋅I
Example 6
---------
An overhanging beam of length 11 meters is subjected to a distributed constant
load of 2 KN/m from 2 meters away from the starting point till 6 meters away
from it. It is pinned at the starting point and is resting over a roller 8 meters
away from that end. Also a counterclockwise moment of 5 KN-m is applied at the
overhanging end.
::
2 KN/m ---> x
_________________ |
| | | | | | | | | v y
V V V V V V V V V ⭯ 5 KN-m
____________________________________________________|
O____________________________________________________|
/ \ /\
|--------|----------------|----------|---------------|
2m 4m 2m 3m
.. code:: pycon
>>> R1, R2 = symbols('R1, R2')
>>> E, I = symbols('E, I')
>>> b = Beam(11, E, I)
>>> b.apply_load(R1, 0, -1)
>>> b.apply_load(2, 2, 0, end=6)
>>> b.apply_load(R2, 8, -1)
>>> b.apply_load(5, 11, -2)
>>> b.solve_for_reaction_loads(R1, R2)
>>> b.reaction_loads
{R₁: -37/8, R₂: -27/8}
>>> b.load
-1 -1
37⋅<x> 0 0 27⋅<x - 8> -2
- ──────── + 2⋅<x - 2> - 2⋅<x - 6> - ──────────── + 5⋅<x - 11>
8 8
>>> b.shear_force()
0 0
37⋅<x> 1 1 27⋅<x - 8> -1
- ─────── + 2⋅<x - 2> - 2⋅<x - 6> - ─────────── + 5⋅<x - 11>
8 8
>>> b.bending_moment()
1 1
37⋅<x> 2 2 27⋅<x - 8> 0
- ─────── + <x - 2> - <x - 6> - ─────────── + 5⋅<x - 11>
8 8
>>> b.bc_deflection = [(0, 0), (8, 0)]
>>> b.slope()
2 3 3 2
37⋅<x> <x - 2> <x - 6> 27⋅<x - 8> 1
- ─────── + ──────── - ──────── - ─────────── + 5⋅<x - 11> + 36
16 3 3 16
────────────────────────────────────────────────────────────────
E⋅I
>>> b.deflection()
3 4 4 3 2
37⋅<x> <x - 2> <x - 6> 9⋅<x - 8> 5⋅<x - 11>
36⋅x - ─────── + ──────── - ──────── - ────────── + ───────────
48 12 12 16 2
───────────────────────────────────────────────────────────────
E⋅I
Example 7
---------
There is a beam of length ``l``, fixed at both ends. A concentrated point load
of magnitude ``F`` is applied in downward direction at mid-point of the
beam.
::
^ y
|
---> x
\\\\| F |\\\\
\\\\| | |\\\\
\\\\| V |\\\\
\\\\|_____________________________________|\\\\
\\\\|_____________________________________|\\\\
\\\\| : |\\\\
\\\\| : |\\\\
\\\\|------------------|------------------|\\\\
l/2 l/2
.. code:: pycon
>>> from sympy.physics.continuum_mechanics.beam import Beam
>>> from sympy import symbols
>>> E, I, F = symbols('E I F')
>>> l = symbols('l', positive=True)
>>> b = Beam(l, E, I)
>>> R1,R2 = symbols('R1 R2')
>>> M1, M2 = symbols('M1, M2')
>>> b.apply_load(R1, 0, -1)
>>> b.apply_load(M1, 0, -2)
>>> b.apply_load(R2, l, -1)
>>> b.apply_load(M2, l, -2)
>>> b.apply_load(-F, l/2, -1)
>>> b.bc_deflection = [(0, 0),(l, 0)]
>>> b.bc_slope = [(0, 0),(l, 0)]
>>> b.solve_for_reaction_loads(R1, R2, M1, M2)
>>> b.reaction_loads
⎧ -F⋅l F⋅l F F⎫
⎨M₁: ─────, M₂: ───, R₁: ─, R₂: ─⎬
⎩ 8 8 2 2⎭
>>> b.load
-2 -2 -1 -1 -1
F⋅l⋅<x> F⋅l⋅<-l + x> F⋅<x> l F⋅<-l + x>
- ───────── + ────────────── + ─────── - F⋅<- ─ + x> + ────────────
8 8 2 2 2
>>> b.shear_force()
-1 -1 0 0 0
F⋅l⋅<x> F⋅l⋅<-l + x> F⋅<x> l F⋅<-l + x>
- ───────── + ────────────── + ────── - F⋅<- ─ + x> + ───────────
8 8 2 2 2
>>> b.bending_moment()
0 0 1 1 1
F⋅l⋅<x> F⋅l⋅<-l + x> F⋅<x> l F⋅<-l + x>
- ──────── + ───────────── + ────── - F⋅<- ─ + x> + ───────────
8 8 2 2 2
>>> b.slope()
2
l
1 1 2 F⋅<- ─ + x> 2
F⋅l⋅<x> F⋅l⋅<-l + x> F⋅<x> 2 F⋅<-l + x>
- ──────── + ───────────── + ────── - ──────────── + ───────────
8 8 4 2 4
────────────────────────────────────────────────────────────────
E⋅I
>>> b.deflection()
3
l
2 2 3 F⋅<- ─ + x> 3
F⋅l⋅<x> F⋅l⋅<-l + x> F⋅<x> 2 F⋅<-l + x>
- ──────── + ───────────── + ────── - ──────────── + ───────────
16 16 12 6 12
────────────────────────────────────────────────────────────────
E⋅I
Example 8
---------
There is a beam of length ``4*l``, having a hinge connector at the middle. It
is having a fixed support at the start and also has two rollers at a distance
of ``l`` and ``4*l`` from the starting point. A concentrated point load ``P`` is also
applied at a distance of ``3*l`` from the starting point.
::
---> x
\\\\| P |
\\\\| | v y
\\\\| V
\\\\|_____________________ _______________________
\\\\|_____________________O_______________________|
\\\\| /\ : /\
\\\\| oooo : oooo
\\\\|----------|-----------|----------|-----------|
l l l l
.. code:: pycon
>>> from sympy.physics.continuum_mechanics.beam import Beam
>>> from sympy import symbols
>>> E, I = symbols('E I')
>>> l = symbols('l', positive=True)
>>> R1, M1, R2, R3, P = symbols('R1 M1 R2 R3 P')
>>> b1 = Beam(2*l, E, I)
>>> b2 = Beam(2*l, E, I)
>>> b = b1.join(b2, "hinge")
>>> b.apply_load(M1, 0, -2)
>>> b.apply_load(R1, 0, -1)
>>> b.apply_load(R2, l, -1)
>>> b.apply_load(R3, 4*l, -1)
>>> b.apply_load(P, 3*l, -1)
>>> b.bc_slope = [(0, 0)]
>>> b.bc_deflection = [(0, 0), (l, 0), (4*l, 0)]
>>> b.solve_for_reaction_loads(M1, R1, R2, R3)
>>> b.reaction_loads
⎧ -P⋅l 3⋅P -5⋅P -P ⎫
⎨M₁: ─────, R₁: ───, R₂: ─────, R₃: ───⎬
⎩ 4 4 4 2 ⎭
>>> b.load
-2 -1 -1 -1
P⋅l⋅<x> 3⋅P⋅<x> 5⋅P⋅<-l + x> -1 P⋅<-4⋅l + x>
- ───────── + ───────── - ────────────── + P⋅<-3⋅l + x> - ──────────────
4 4 4 2
>>> b.shear_force()
-1 0 0 0
P⋅l⋅<x> 3⋅P⋅<x> 5⋅P⋅<-l + x> 0 P⋅<-4⋅l + x>
- ───────── + ──────── - ───────────── + P⋅<-3⋅l + x> - ─────────────
4 4 4 2
>>> b.bending_moment()
0 1 1 1
P⋅l⋅<x> 3⋅P⋅<x> 5⋅P⋅<-l + x> 1 P⋅<-4⋅l + x>
- ──────── + ──────── - ───────────── + P⋅<-3⋅l + x> - ─────────────
4 4 4 2
>>> b.slope()
⎛ 2 2 2 2⎞ ⎛ 1 2 2 2⎞ ⎛ 1 2 2 2⎞
⎜5⋅P⋅l P⋅<-2⋅l + x> P⋅<-3⋅l + x> P⋅<-4⋅l + x> ⎟ 0 ⎜ P⋅l⋅<x> 3⋅P⋅<x> 5⋅P⋅<-l + x> P⋅<-2⋅l + x> ⎟ 0 ⎜ P⋅l⋅<x> 3⋅P⋅<x> 5⋅P⋅<-l + x> P⋅<-2⋅l + x> ⎟ 0
⎜────── - ───────────── + ───────────── - ─────────────⎟⋅<-2⋅l + x> ⎜- ──────── + ──────── - ───────────── + ─────────────⎟⋅<x> ⎜- ──────── + ──────── - ───────────── + ─────────────⎟⋅<-2⋅l + x>
⎝ 48 4 2 4 ⎠ ⎝ 4 8 8 4 ⎠ ⎝ 4 8 8 4 ⎠
──────────────────────────────────────────────────────────────────── + ──────────────────────────────────────────────────────────── - ───────────────────────────────────────────────────────────────────
E⋅I E⋅I E⋅I
>>> b.deflection()
⎛ 2 3 3 3⎞ ⎛ 2 3 3 3⎞ ⎛ 3 2 3 3 3⎞
⎜ P⋅l⋅<x> P⋅<x> 5⋅P⋅<-l + x> P⋅<-2⋅l + x> ⎟ 0 ⎜ P⋅l⋅<x> P⋅<x> 5⋅P⋅<-l + x> P⋅<-2⋅l + x> ⎟ 0 ⎜7⋅P⋅l 5⋅P⋅l ⋅(-2⋅l + x) P⋅<-2⋅l + x> P⋅<-3⋅l + x> P⋅<-4⋅l + x> ⎟ 0
⎜- ──────── + ────── - ───────────── + ─────────────⎟⋅<x> ⎜- ──────── + ────── - ───────────── + ─────────────⎟⋅<-2⋅l + x> ⎜────── + ───────────────── - ───────────── + ───────────── - ─────────────⎟⋅<-2⋅l + x>
⎝ 8 8 24 12 ⎠ ⎝ 8 8 24 12 ⎠ ⎝ 24 48 12 6 12 ⎠
────────────────────────────────────────────────────────── - ───────────────────────────────────────────────────────────────── + ────────────────────────────────────────────────────────────────────────────────────────
E⋅I E⋅I E⋅I
Example 9
---------
There is a cantilever beam of length 4 meters. For first 2 meters
its moment of inertia is ``1.5*I`` and ``I`` for the rest.
A pointload of magnitude 20 N is applied from the top at its free end.
::
---> x
\\\\| |
\\\\| 20 N v y
\\\\|________________ |
\\\\| |_______________V
\\\\| 1.5*I _______I_______|
\\\\|________________|
\\\\| :
\\\\|----------------|---------------|
2.0 m 2.0 m
.. code:: pycon
>>> from sympy.physics.continuum_mechanics.beam import Beam
>>> from sympy import symbols
>>> E, I = symbols('E, I')
>>> R1, R2 = symbols('R1, R2')
>>> b1 = Beam(2, E, 1.5*I)
>>> b2 = Beam(2, E, I)
>>> b = b1.join(b2, "fixed")
>>> b.apply_load(20, 4, -1)
>>> b.apply_load(R1, 0, -1)
>>> b.apply_load(R2, 0, -2)
>>> b.bc_slope = [(0, 0)]
>>> b.bc_deflection = [(0, 0)]
>>> b.solve_for_reaction_loads(R1, R2)
>>> b.load
-2 -1 -1
80⋅<x> - 20⋅<x> + 20⋅<x - 4>
>>> b.shear_force()
-1 0 0
80⋅<x> - 20⋅<x> + 20⋅<x - 4>
>>> b.bending_moment()
0 1 1
80⋅<x> - 20⋅<x> + 20⋅<x - 4>
>>> b.slope()
⎛ 1 2 2 ⎞
⎜80⋅<x> - 10⋅<x> + 10⋅<x - 4> 120 ⎟
⎜─────────────────────────────── - ─── ⎟ ⎛ 1 2 2⎞ 0 ⎛ 1 2 2⎞ 0
⎜ I I 80.0⎟ 0 0.666666666666667⋅⎝80⋅<x> - 10⋅<x> + 10⋅<x - 4> ⎠⋅<x> 0.666666666666667⋅⎝80⋅<x> - 10⋅<x> + 10⋅<x - 4> ⎠⋅<x - 2>
⎜───────────────────────────────────── + ────⎟⋅<x - 2> + ──────────────────────────────────────────────────────── - ────────────────────────────────────────────────────────────
⎝ E E⋅I ⎠ E⋅I E⋅I
Example 10
----------
A combined beam, with constant flexural rigidity ``E*I``, is formed by joining
a Beam of length ``2*l`` to the right of another Beam of length ``l``. The whole beam
is fixed at both of its ends. A point load of magnitude ``P`` is also applied
from the top at a distance of ``2*l`` from starting point.
::
---> x
|
\\\\| P v y |\\\\
\\\\| | |\\\\
\\\\| V |\\\\
\\\\|____________ ________________________|\\\\
\\\\|____________O________________________|\\\\
\\\\| : : |\\\\
\\\\| : : |\\\\
\\\\|------------|------------|-----------|\\\\
l l l
.. code:: pycon
>>> from sympy.physics.continuum_mechanics.beam import Beam
>>> from sympy import symbols
>>> E, I = symbols('E, I')
>>> l = symbols('l', positive=True)
>>> b1 = Beam(l ,E,I)
>>> b2 = Beam(2*l ,E,I)
>>> b = b1.join(b2,"hinge")
>>> M1, A1, M2, A2, P = symbols('M1 A1 M2 A2 P')
>>> b.apply_load(A1, 0, -1)
>>> b.apply_load(M1, 0 ,-2)
>>> b.apply_load(P, 2*l, -1)
>>> b.apply_load(A2, 3*l, -1)
>>> b.apply_load(M2, 3*l, -2)
>>> b.bc_slope=[(0, 0), (3*l, 0)]
>>> b.bc_deflection=[(0, 0), (3*l, 0)]
>>> b.solve_for_reaction_loads(M1, A1, M2, A2)
>>> b.reaction_loads
⎧ -5⋅P -13⋅P 5⋅P⋅l -4⋅P⋅l ⎫
⎨A₁: ─────, A₂: ──────, M₁: ─────, M₂: ───────⎬
⎩ 18 18 18 9 ⎭
>>> b.load
-2 -2 -1 -1
5⋅P⋅l⋅<x> 4⋅P⋅l⋅<-3⋅l + x> 5⋅P⋅<x> -1 13⋅P⋅<-3⋅l + x>
─────────── - ────────────────── - ───────── + P⋅<-2⋅l + x> - ─────────────────
18 9 18 18
>>> b.shear_force()
-1 -1 0 0
5⋅P⋅l⋅<x> 4⋅P⋅l⋅<-3⋅l + x> 5⋅P⋅<x> 0 13⋅P⋅<-3⋅l + x>
─────────── - ────────────────── - ──────── + P⋅<-2⋅l + x> - ────────────────
18 9 18 18
>>> b.bending_moment()
0 0 1 1
5⋅P⋅l⋅<x> 4⋅P⋅l⋅<-3⋅l + x> 5⋅P⋅<x> 1 13⋅P⋅<-3⋅l + x>
────────── - ───────────────── - ──────── + P⋅<-2⋅l + x> - ────────────────
18 9 18 18
>>> b.slope()
⎛ 1 2 2⎞ ⎛ 1 2 2⎞ ⎛ 2 1 2 2 2⎞
⎜5⋅P⋅l⋅<x> 5⋅P⋅<x> 5⋅P⋅<-l + x> ⎟ 0 ⎜5⋅P⋅l⋅<x> 5⋅P⋅<x> 5⋅P⋅<-l + x> ⎟ 0 ⎜P⋅l 4⋅P⋅l⋅<-3⋅l + x> 5⋅P⋅<-l + x> P⋅<-2⋅l + x> 13⋅P⋅<-3⋅l + x> ⎟ 0
⎜────────── - ──────── + ─────────────⎟⋅<x> ⎜────────── - ──────── + ─────────────⎟⋅<-l + x> ⎜──── - ───────────────── - ───────────── + ───────────── - ────────────────⎟⋅<-l + x>
⎝ 18 36 36 ⎠ ⎝ 18 36 36 ⎠ ⎝ 18 9 36 2 36 ⎠
──────────────────────────────────────────── - ───────────────────────────────────────────────── + ───────────────────────────────────────────────────────────────────────────────────────
E⋅I E⋅I E⋅I
>>> b.deflection()
⎛ 2 3 3⎞ ⎛ 2 3 3⎞ ⎛ 3 2 2 3 3 3⎞
⎜5⋅P⋅l⋅<x> 5⋅P⋅<x> 5⋅P⋅<-l + x> ⎟ 0 ⎜5⋅P⋅l⋅<x> 5⋅P⋅<x> 5⋅P⋅<-l + x> ⎟ 0 ⎜5⋅P⋅l P⋅l ⋅(-l + x) 2⋅P⋅l⋅<-3⋅l + x> 5⋅P⋅<-l + x> P⋅<-2⋅l + x> 13⋅P⋅<-3⋅l + x> ⎟ 0
⎜────────── - ──────── + ─────────────⎟⋅<x> ⎜────────── - ──────── + ─────────────⎟⋅<-l + x> ⎜────── + ───────────── - ───────────────── - ───────────── + ───────────── - ────────────────⎟⋅<-l + x>
⎝ 36 108 108 ⎠ ⎝ 36 108 108 ⎠ ⎝ 54 18 9 108 6 108 ⎠
──────────────────────────────────────────── - ───────────────────────────────────────────────── + ─────────────────────────────────────────────────────────────────────────────────────────────────────────
E⋅I E⋅I E⋅I
Example 11
----------
Any type of load defined by a polynomial can be applied to the beam. This
allows approximation of arbitrary load distributions. The following example
shows six truncated polynomial loads across the surface of a beam.
.. plot::
:context: close-figs
:format: doctest
:include-source: True
>>> n = 6
>>> b = Beam(10*n, E, I)
>>> for i in range(n):
... b.apply_load(1 / (5**i), 10*i + 5, i, end=10*i + 10)
>>> plot(b.load, (x, 0, 10*n)) # doctest: +SKIP
E⋅I
+3 -3
View File
@@ -1,8 +1,8 @@
.. _physics-docs:
=======
Physics
=======
==============
Physics Module
==============
.. automodule:: sympy.physics
@@ -1,5 +1,3 @@
.. _kane_lagrange:
==============================================
Kane's Method & Lagrange's Method (Docstrings)
==============================================
@@ -1,5 +1,3 @@
.. _part_bod:
=====================================================
Masses, Inertias & Particles, RigidBodys (Docstrings)
=====================================================
@@ -1,596 +0,0 @@
.. _autolev_parser:
==============
Autolev Parser
==============
.. role:: input(strong)
Introduction
============
Autolev (now superseded by MotionGenesis) is a domain specific language
used for symbolic multibody dynamics. The SymPy mechanics module now has
enough power and functionality to be a fully featured symbolic dynamics
module. This parser parses Autolev (version 4.1) code to SymPy code by making
use of SymPy's math libraries and the mechanics module.
The parser has been built using the `ANTLR <http://www.antlr.org/>`_ framework and its main purpose
is to help former users of Autolev to get familiarized with multibody dynamics
in SymPy.
The sections below shall discuss details of the parser like usage, gotchas,
issues and future improvements.
For a detailed comparison of Autolev and SymPy Mechanics you might want to look at
the :ref:`SymPy Mechanics for Autolev Users guide <sympy_mechanics_for_autolev_users>`.
.. _usage:
Usage
=====
We first start with an Autolev code file.
Let us take this example
(Comments ``%`` have been included to show the Autolev responses):
.. code-block:: none
% double_pendulum.al
%-------------------
MOTIONVARIABLES' Q{2}', U{2}'
CONSTANTS L,M,G
NEWTONIAN N
FRAMES A,B
SIMPROT(N, A, 3, Q1)
% -> N_A = [COS(Q1), -SIN(Q1), 0; SIN(Q1), COS(Q1), 0; 0, 0, 1]
SIMPROT(N, B, 3, Q2)
% -> N_B = [COS(Q2), -SIN(Q2), 0; SIN(Q2), COS(Q2), 0; 0, 0, 1]
W_A_N>=U1*N3>
% -> W_A_N> = U1*N3>
W_B_N>=U2*N3>
% -> W_B_N> = U2*N3>
POINT O
PARTICLES P,R
P_O_P> = L*A1>
% -> P_O_P> = L*A1>
P_P_R> = L*B1>
% -> P_P_R> = L*B1>
V_O_N> = 0>
% -> V_O_N> = 0>
V2PTS(N, A, O, P)
% -> V_P_N> = L*U1*A2>
V2PTS(N, B, P, R)
% -> V_R_N> = L*U1*A2> + L*U2*B2>
MASS P=M, R=M
Q1' = U1
Q2' = U2
GRAVITY(G*N1>)
% -> FORCE_P> = G*M*N1>
% -> FORCE_R> = G*M*N1>
ZERO = FR() + FRSTAR()
% -> ZERO[1] = -L*M*(2*G*SIN(Q1)+L*(U2^2*SIN(Q1-Q2)+2*U1'+COS(Q1-Q2)*U2'))
% -> ZERO[2] = -L*M*(G*SIN(Q2)-L*(U1^2*SIN(Q1-Q2)-U2'-COS(Q1-Q2)*U1'))
KANE()
INPUT M=1,G=9.81,L=1
INPUT Q1=.1,Q2=.2,U1=0,U2=0
INPUT TFINAL=10, INTEGSTP=.01
CODE DYNAMICS() some_filename.c
The parser can be used as follows::
>>> from sympy.parsing.autolev import parse_autolev
>>> sympy_code = parse_autolev(open('double_pendulum.al'), include_numeric=True)
# The include_pydy flag is False by default. Setting it to True will
# enable PyDy simulation code to be outputted if applicable.
>>> print(sympy_code)
import sympy.physics.mechanics as me
import sympy as sm
import math as m
import numpy as np
q1, q2, u1, u2 = me.dynamicsymbols('q1 q2 u1 u2')
q1d, q2d, u1d, u2d = me.dynamicsymbols('q1 q2 u1 u2', 1)
l, m, g=sm.symbols('l m g', real=True)
frame_n=me.ReferenceFrame('n')
frame_a=me.ReferenceFrame('a')
frame_b=me.ReferenceFrame('b')
frame_a.orient(frame_n, 'Axis', [q1, frame_n.z])
# print(frame_n.dcm(frame_a))
frame_b.orient(frame_n, 'Axis', [q2, frame_n.z])
# print(frame_n.dcm(frame_b))
frame_a.set_ang_vel(frame_n, u1*frame_n.z)
# print(frame_a.ang_vel_in(frame_n))
frame_b.set_ang_vel(frame_n, u2*frame_n.z)
# print(frame_b.ang_vel_in(frame_n))
point_o=me.Point('o')
particle_p=me.Particle('p', me.Point('p_pt'), sm.Symbol('m'))
particle_r=me.Particle('r', me.Point('r_pt'), sm.Symbol('m'))
particle_p.point.set_pos(point_o, l*frame_a.x)
# print(particle_p.point.pos_from(point_o))
particle_r.point.set_pos(particle_p.point, l*frame_b.x)
# print(particle_p.point.pos_from(particle_r.point))
point_o.set_vel(frame_n, 0)
# print(point_o.vel(frame_n))
particle_p.point.v2pt_theory(point_o,frame_n,frame_a)
# print(particle_p.point.vel(frame_n))
particle_r.point.v2pt_theory(particle_p.point,frame_n,frame_b)
# print(particle_r.point.vel(frame_n))
particle_p.mass = m
particle_r.mass = m
force_p = particle_p.mass*(g*frame_n.x)
# print(force_p)
force_r = particle_r.mass*(g*frame_n.x)
# print(force_r)
kd_eqs = [q1d - u1, q2d - u2]
forceList = [(particle_p.point,particle_p.mass*(g*frame_n.x)), (particle_r.point,particle_r.mass*(g*frame_n.x))]
kane = me.KanesMethod(frame_n, q_ind=[q1,q2], u_ind=[u1, u2], kd_eqs = kd_eqs)
fr, frstar = kane.kanes_equations([particle_p, particle_r], forceList)
zero = fr+frstar
# print(zero)
#---------PyDy code for integration----------
from pydy.system import System
sys = System(kane, constants = {l:1, m:1, g:9.81},
specifieds={},
initial_conditions={q1:.1, q2:.2, u1:0, u2:0},
times = np.linspace(0.0, 10, 10/.01))
y=sys.integrate()
The commented code is not part of the output code. The print
statements demonstrate how to get responses similar to the ones in the
Autolev file.
Note that we need to use SymPy functions like ``.ang_vel_in()``, ``.dcm()``
etc in many cases unlike directly printing out the variables like ``zero``.
If you are completely new to SymPy mechanics, the :ref:`SymPy Mechanics for Autolev Users guide <sympy_mechanics_for_autolev_users>`
guide should help. You might also have to use basic SymPy simplifications
and manipulations like ``trigsimp()``, ``expand()``, ``evalf()`` etc for
getting outputs similar to Autolev.
Refer to the `SymPy Tutorial <https://docs.sympy.org/latest/tutorial/index.html>`_
to know more about these.
.. _gotchas_autolev:
Gotchas
=======
- Don't use variable names that conflict with Python's reserved words.
This is one example where this is violated:
.. code-block:: none
%Autolev Code
%------------
LAMBDA = EIG(M)
.. code-block:: python
#SymPy Code
#----------
lambda = sm.Matrix([i.evalf() for i in (m).eigenvals().keys()])
------------------------------------------------------------------------
- Make sure that the names of vectors and scalars are different.
Autolev treats these differently but these will get overwritten in Python.
The parser currently allows the names of bodies and scalars/vectors to
coincide but doesn't do this between scalars and vectors.
This should probably be changed in the future.
.. code-block:: none
%Autolev Code
%------------
VARIABLES X,Y
FRAMES A
A> = X*A1> + Y*A2>
A = X+Y
.. code-block:: python
#SymPy Code
#----------
x, y = me.dynamicsymbols('x y')
frame_a = me.ReferenceFrame('a')
a = x*frame_a.x + y*frame_a.y
a = x + y
# Note how frame_a is named differently so it doesn't cause a problem.
# On the other hand, 'a' gets rewritten from a scalar to a vector.
# This should be changed in the future.
------------------------------------------------------------------------
- When dealing with Matrices returned by functions, one must check the
order of the values as they may not be the same as in Autolev. This is
especially the case for eigenvalues and eigenvectors.
.. code-block:: none
%Autolev Code
%------------
EIG(M, E1, E2)
% -> [5; 14; 13]
E2ROW = ROWS(E2, 1)
EIGVEC> = VECTOR(A, E2ROW)
.. code-block:: python
#SymPy Code
#----------
e1 = sm.Matrix([i.evalf() for i in m.eigenvals().keys()])
# sm.Matrix([5;13;14]) different order
e2 = sm.Matrix([i[2][0].evalf() for i in m.eigenvects()]).reshape(m.shape[0], m.shape[1])
e2row = e2.row(0)
# This result depends on the order of the vectors in the eigenvecs.
eigenvec = e2row[0]*a.x + e2row[1]*a.y + e2row[2]*a.y
------------------------------------------------------------------------
- When using ``EVALUATE``, use something like ``90*UNITS(deg,rad)`` for
angle substitutions as radians are the default in SymPy.
You could also add ``np.deg2rad()`` directly in the SymPy code.
This need not be done for the output code (generated on parsing the
``CODE`` commands) as the parser takes care of this when ``deg`` units
are given in the ``INPUT`` declarations.
The ``DEGREES`` setting, on the other hand, works only in some cases like
in ``SIMPROT`` where an angle is expected.
.. code-block:: none
%Autolev Code
%------------
A> = Q1*A1> + Q2*A2>
B> = EVALUATE(A>, Q1:30*UNITS(DEG,RAD))
.. code-block:: python
#SymPy Code
#----------
a = q1*a.frame_a.x + q2*frame_a.y
b = a.subs({q1:30*0.0174533})
# b = a.subs({q1:np.deg2rad(30)}
------------------------------------------------------------------------
- Most of the Autolev settings have not been parsed and have no effect on the parser.
The only ones that work somewhat are ``COMPLEX`` and ``DEGREES``.
It is advised to look into alternatives to these in SymPy and Python.
------------------------------------------------------------------------
- The ``REPRESENT`` command is not supported.
Use the ``MATRIX``, ``VECTOR`` or ``DYADIC`` commands instead.
Autolev 4.1 suggests these over ``REPRESENT`` as well while still allowing
it but the parser doesn't parse it.
------------------------------------------------------------------------
- Do not use variables declarations of the type ``WO{3}RD{2,4}``.
The parser can only handle one variable name followed by one pair
of curly braces and any number of ``'`` s.
You would have to declare all the cases manually if you want to achieve
something like ``WO{3}RD{2,4}``.
------------------------------------------------------------------------
- The parser can handle normal versions of most commands but it may not
parse functions with Matrix arguments properly in most cases.
Eg:
``M=COEF([E1;E2],[U1,U2,U3])``
This would compute the coefficients of ``U1``, ``U2`` and ``U3`` in ``E1``
and ``E2``. It is preferable to manually construct a Matrix using the
regular versions of these commands.
.. code-block:: none
%Autolev Code
%------------
% COEF([E1;E2],[U1,U2,U3])
M = [COEF(E1,U1),COEF(E1,U2),COEF(E1,U3) &
;COEF(E2,U1),COEF(E2,U2),COEF(E2,U3)]
------------------------------------------------------------------------
- ``MOTIONVARIABLE`` declarations must be used for the generalized coordinates
and speeds and all other variables must be declared in regular
``VARIABLE`` declarations.
The parser requires this to distinguish between them to pass the correct
parameters to the Kane's method object.
It is also preferred to always declare the speeds corresponding to the
coordinates and to pass in the kinematic differential equations.
The parser is able to handle some cases where this isn't the case by
introducing some dummy variables of its own but SymPy on its own
does require them.
Also note that older Autolev declarations like ``VARIABLES U{3}'`` are not
supported either.
.. code-block:: none
%Autolev Code
%------------
MOTIONVARIABLES' Q{2}', U{2}'
% ----- OTHER LINES ----
Q1' = U1
Q2' = U2
----- OTHER LINES ----
ZERO = FR() + FRSTAR()
.. code-block:: python
#SymPy Code
#----------
q1, q2, u1, u2 = me.dynamicsymbols('q1 q2 u1 u2')
q1d, q2d, u1d, u2d = me.dynamicsymbols('q1 q2 u1 u2', 1)
# ------- other lines -------
kd_eqs = [q1d - u1, q2d - u2]
kane = me.KanesMethod(frame_n, q_ind=[q1,q2], u_ind=[u1, u2], kd_eqs = kd_eqs)
fr, frstar = kane.kanes_equations([particle_p, particle_r], forceList)
zero = fr+frstar
------------------------------------------------------------------------
- Need to change ``me.dynamicsymbols._t`` to ``me.dynamicsymbols('t')`` for
all occurrences of it in the Kane's equations. For example have a look at
line 10 of this `spring damper example <https://github.com/sympy/sympy/blob/master/sympy/parsing/autolev/test_examples/mass_spring_damper.py>`_.
This equation is used in forming the Kane's equations so we need to
change ``me.dynamicsymbols._t`` to ``me.dynamicsymbols('t')`` in this case.
The main reason that this needs to be done is because PyDy
requires time dependent specifieds to be explicitly laid out while
Autolev simply takes care of the stray time variables in the equations
by itself.
The problem is that PyDy's System class does not accept
``dynamicsymbols._t`` as a specified. Refer to issue `#396 <https://github.com/pydy/pydy/issues/396>`_.
This change is not actually ideal so a better solution should be figured
out in the future.
------------------------------------------------------------------------
- The parser creates SymPy ``symbols`` and ``dynamicsymbols`` by parsing
variable declarations in the Autolev Code.
For intermediate expressions which are directly initialized the parser
does not create SymPy symbols. It just assigns them to the expression.
On the other hand, when a declared variable is assigned to an expression,
the parser stores the expression against the variable in a dictionary so
as to not reassign it to a completely different entity. This constraint
is due to the inherent nature of Python and how it differs from a language
like Autolev.
Also, Autolev seems to be able to assume whether to use a variable or the
rhs expression that variable has been assigned to in equations even
without an explicit ``RHS()`` call in some cases.
For the parser to work correctly however, it is better to use ``RHS()``
wherever a variable's rhs expression is meant to be used.
.. code-block:: none
%Autolev Code
%------------
VARIABLES X, Y
E = X + Y
X = 2*Y
RHS_X = RHS(X)
I1 = X
I2 = Y
I3 = X + Y
INERTIA B,I1,I2,I3
% -> I_B_BO>> = I1*B1>*B1> + I2*B2>*B2> + I3*B3>*B3>
.. code-block:: python
#SymPy Code
#----------
x,y = me.dynamicsymbols('x y')
e = x + y # No symbol is made out of 'e'
# an entry like {x:2*y} is stored in an rhs dictionary
rhs_x = 2*y
i1 = x # again these are not made into SymPy symbols
i2 = y
i3 = x + y
body_b.inertia = (me.inertia(body_b_f, i1, i2, i3), b_cm)
# This prints as:
# x*b_f.x*b_f.x + y*b_f.y*b_f.y + (x+y)*b_f.z*b_f.z
# while Autolev's output has I1,I2 and I3 in it.
# Autolev however seems to know when to use the RHS of I1,I2 and I3
# based on the context.
------------------------------------------------------------------------
- This is how the ``SOLVE`` command is parsed:
.. code-block:: none
%Autolev Code
%------------
SOLVE(ZERO,X,Y)
A = RHS(X)*2 + RHS(Y)
.. code-block:: python
#SymPy Code
#----------
print(sm.solve(zero,x,y))
# Behind the scenes the rhs of x
# is set to sm.solve(zero,x,y)[x].
a = sm.solve(zero,x,y)[x]*2 + sm.solve(zero,x,y)[y]
The indexing like ``[x]`` and ``[y]`` doesn't always work so you might want to
look at the underlying dictionary that solve returns and index it correctly.
------------------------------------------------------------------------
- Inertia declarations and Inertia functions work somewhat differently in
the context of the parser. This might be hard to understand at first
but this had to be done to bridge the gap due to the differences in
SymPy and Autolev. Here are some points about them:
1. Inertia declarations (``INERTIA B,I1,I2,I3``) set the inertias of rigid
bodies.
2. Inertia setters of the form ``I_C_D>> = expr`` however, set the inertias
only when C is a body. If C is a particle then ``I_C_D>> = expr``
simply parses to ``i_c_d = expr`` and ``i_c_d`` acts like a regular variable.
3. When it comes to inertia getters (``I_C_D>>`` used in an expression or
``INERTIA`` commands), these MUST be used with the ``EXPRESS`` command
to specify the frame as SymPy needs this information to compute the
inertia dyadic.
.. code-block:: none
%Autolev Code
%------------
INERTIA B,I1,I2,I3
I_B_BO>> = X*A1>*A1> + Y*A2>*A2> % Parser will set the inertia of B
I_P_Q>> = X*A1>*A1> + Y^2*A2>*A2> % Parser just parses it as i_p_q = expr
E1 = 2*EXPRESS(I_B_O>>,A)
E2 = I_P_Q>>
E3 = EXPRESS(I_P_O>>,A)
E4 = EXPRESS(INERTIA(O),A)
% In E1 we are using the EXPRESS command with I_B_O>> which makes
% the parser and SymPy compute the inertia of Body B about point O.
% In E2 we are just using the dyadic object I_P_Q>> (as I_P_Q>> = expr
% doesn't act as a setter) defined above and not asking the parser
% or SymPy to compute anything.
% E3 asks the parser to compute the inertia of P about point O.
% E4 asks the parser to compute the inertias of all bodies wrt about O.
------------------------------------------------------------------------
- In an inertia declaration of a body, if the inertia is being set about
a point other than the center of mass, one needs to make sure that
the position vector setter for that point and the center of mass appears
before the inertia declaration as SymPy will throw an error otherwise.
.. code-block:: none
%Autolev Code
%------------
P_SO_O> = X*A1>
INERTIA S_(O) I1,I2,I3
------------------------------------------------------------------------
- Note that all Autolev commands have not been implemented. The parser
now covers the important ones in their basic forms. If you are doubtful
whether a command is included or not, please have a look at `this file <https://github.com/sympy/sympy/blob/master/sympy/parsing/autolev/_listener_autolev_antlr.py>`_
in the source code. Search for "<command>" to verify this. Looking at the
code for the specific command will also give an idea about what form it
is expected to work in.
.. _issues:
Limitations and Issues
======================
- A lot of the issues have already been discussed in the Gotchas section.
Some of these are:
- Vector names coinciding with scalar names are overwritten in Python.
- Some convenient variable declarations aren't parsed.
- Some convenient forms of functions to return matrices aren't parsed.
- Settings aren't parsed.
- symbols and rhs expressions work very differently in Python which might
cause undesirable results.
- Dictionary indexing for the parsed code of the ``SOLVE`` command is
not proper in many cases.
- Need to change ``dynamicsymbols._t`` to ``dynamicsymbols('t')`` for the
PyDy simulation code to work properly.
Here are some other ones:
- Eigenvectors do not seem to work as expected. The values in Autolev and SymPy
are not the same in many cases.
- Block matrices aren't parsed by the parser. It would actually be easier
to make a change in SymPy to allow matrices to accept other matrices for
arguments.
- The SymPy equivalent of the ``TAYLOR`` command ``.series()`` does not work
with ``dynamicsymbols()``.
- Only ``DEPENDENT`` constraints are currently parsed. Need to parse
``AUXILIARY`` constraints as well. This should be done soon as it isn't
very difficult.
- None of the energy and momentum functions are parsed right now. It would
be nice to get these working as well. Some changes should probably be made
to SymPy. For instance, SymPy doesn't have a function equivalent to ``NICHECK()``.
- The numerical integration parts work properly only in the case of the
``KANE`` command with no arguments. Things like ``KANE(F1,F2)`` do not currently
work.
- Also, the PyDy numerical simulation code works only for cases where the
matrix say ``ZERO = FR() + FRSTAR()`` is solved for. It doesn't work well when the
matrix has some other equations plugged in as well. One hurdle
faced in achieving this was that PyDy's System class automatically takes
in the ``forcing_full`` and ``mass_matrix_full`` and solves them without giving the
user the flexibility to specify the equations. It would be nice to add
this functionality to the System class.
.. _future_improvements:
Future Improvements
===================
1. Completing Dynamics Online
-----------------------------
The parser has been built by referring to and parsing codes from the
`Autolev Tutorial <http://web.mae.ufl.edu/~fregly/PDFs/autolev_tutorial.pdf>`_
and the book *Dynamics Online: Theory and Implementation Using Autolev*.
Basically, the process involved going through each of these codes,
validating the parser results and improving the rules if required
to make sure the codes parsed well.
The parsed codes of these are available on GitLab `here <https://gitlab.com/sympy/autolev-test-examples>`_.
The repo is private so access needs to be requested.
As of now, most codes till Chapter 4 of *Dynamics Online* have been parsed.
Completing all the remaining codes of the book (namely, *2-10*, *2-11*, *rest
of Ch4*, *Ch5* and *Ch6* (less important) ) would make the parser more complete.
2. Fixing Issues
----------------
The second thing to do would be to go about fixing the problems described
above in the :ref:`Gotchas <gotchas_autolev>` and :ref:`Limitations and Issues <issues>`
sections in order of priority and ease. Many of these require changes
in the parser code while some of these are better fixed by adding some
functionality to SymPy.
3. Switching to an AST
----------------------
The parser is currently built using a kind of Concrete Syntax Tree (CST)
using the `ANTLR <http://www.antlr.org/>`_ framework. It would be ideal to switch from a CST to an
Abstract Syntax Tree (AST). This way, the parser code will be independent
of the ANTLR grammar which makes it a lot more flexible. It would also be
easier to make changes to the grammar and the rules of the parser.
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (https://www.inkscape.org/) -->
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
@@ -9,7 +9,7 @@
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="https://www.inkscape.org/namespaces/inkscape"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="378.90466"
height="456.13843"
id="svg2"

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (https://www.inkscape.org/) -->
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
@@ -8,7 +8,7 @@
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="https://www.inkscape.org/namespaces/inkscape"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="550"
height="550"
id="svg2"

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

@@ -56,12 +56,14 @@ accelerations(q double dots) with the ``rhs`` method. ::
>>> q = [q1, q2, q3]
>>> l = LagrangesMethod(Lag, q)
>>> le = l.form_lagranges_equations()
>>> le.simplify(); le
>>> le = le.simplify()
>>> le
Matrix([
[m*r**2*(6*sin(q2)*q3'' + 5*sin(2*q2)*q1'*q2' + 6*cos(q2)*q2'*q3' - 5*cos(2*q2)*q1''/2 + 7*q1''/2)/4],
[ m*r*(4*g*sin(q2) - 5*r*sin(2*q2)*q1'**2/2 - 6*r*cos(q2)*q1'*q3' + 5*r*q2'')/4],
[ 3*m*r**2*(sin(q2)*q1'' + cos(q2)*q1'*q2' + q3'')/2]])
>>> lrhs = l.rhs(); lrhs.simplify(); lrhs
>>> lrhs = l.rhs().simplify()
>>> lrhs
Matrix([
[ q1'],
[ q2'],
@@ -1,5 +1,3 @@
.. _classical_mechanics:
===================
Classical Mechanics
===================
@@ -83,8 +81,6 @@ Guide to Mechanics
examples.rst
advanced.rst
reference.rst
autolev_parser.rst
sympy_mechanics_for_autolev_users.rst
Mechanics API
=============
@@ -1,5 +1,3 @@
.. _kane_method:
==================================
Kane's Method in Physics/Mechanics
==================================
@@ -3,7 +3,7 @@ Lagrange's Method in Physics/Mechanics
======================================
:mod:`mechanics` provides functionality for deriving equations of motion
using `Lagrange's method <https://en.wikipedia.org/wiki/Lagrangian_mechanics>`_.
using `Lagrange's method <http://en.wikipedia.org/wiki/Lagrangian_mechanics>`_.
This document will describe Lagrange's method as used in this module, but not
how the equations are actually derived.
+51 -57
View File
@@ -1,5 +1,3 @@
.. _masses:
=================================================================
Masses, Inertias, Particles and Rigid Bodies in Physics/Mechanics
=================================================================
@@ -223,42 +221,40 @@ The following example shows how to use the momenta functions in
One begins by creating the requisite symbols to describe the system. Then
the reference frame is created and the kinematics are done. ::
>>> from sympy import symbols
>>> from sympy.physics.mechanics import dynamicsymbols, ReferenceFrame
>>> from sympy.physics.mechanics import RigidBody, Particle, Point, outer
>>> from sympy.physics.mechanics import linear_momentum, angular_momentum
>>> m, M, l1 = symbols('m M l1')
>>> q1d = dynamicsymbols('q1d')
>>> N = ReferenceFrame('N')
>>> O = Point('O')
>>> O.set_vel(N, 0 * N.x)
>>> Ac = O.locatenew('Ac', l1 * N.x)
>>> P = Ac.locatenew('P', l1 * N.x)
>>> a = ReferenceFrame('a')
>>> a.set_ang_vel(N, q1d * N.z)
>>> Ac.v2pt_theory(O, N, a)
l1*q1d*N.y
>>> P.v2pt_theory(O, N, a)
2*l1*q1d*N.y
>> from sympy import symbols
>> from sympy.physics.mechanics import dynamicsymbols, ReferenceFrame
>> from sympy.physics.mechanics import RigidBody, Particle, Point, outer
>> from sympy.physics.mechanics import linear_momentum, angular_momentum
>> m, M, l1 = symbols('m M l1')
>> q1d = dynamicsymbols('q1d')
>> N = ReferenceFrame('N')
>> O = Point('O')
>> O.set_vel(N, 0 * N.x)
>> Ac = O.locatenew('Ac', l1 * N.x)
>> P = Ac.locatenew('P', l1 * N.x)
>> a = ReferenceFrame('a')
>> a.set_ang_vel(N, q1d * N.z)
>> Ac.v2pt_theory(O, N, a)
>> P.v2pt_theory(O, N, a)
Finally, the bodies that make up the system are created. In this case the
system consists of a particle Pa and a RigidBody A. ::
>>> Pa = Particle('Pa', P, m)
>>> I = outer(N.z, N.z)
>>> A = RigidBody('A', Ac, a, M, (I, Ac))
>> Pa = Particle('Pa', P, m)
>> I = outer(N.z, N.z)
>> A = RigidBody('A', Ac, a, M, (I, Ac))
Then one can either choose to evaluate the momenta of individual components
of the system or of the entire system itself. ::
>>> linear_momentum(N,A)
>> linear_momentum(N,A)
M*l1*q1d*N.y
>>> angular_momentum(O, N, Pa)
>> angular_momentum(O, N, Pa)
4*l1**2*m*q1d*N.z
>>> linear_momentum(N, A, Pa)
>> linear_momentum(N, A, Pa)
(M*l1*q1d + 2*l1*m*q1d)*N.y
>>> angular_momentum(O, N, A, Pa)
(M*l1**2*q1d + 4*l1**2*m*q1d + q1d)*N.z
>> angular_momentum(O, N, A, Pa)
(4*l1**2*m*q1d + q1d)*N.z
It should be noted that the user can determine either momenta in any frame
in :mod:`mechanics` as the user is allowed to specify the reference frame when
@@ -327,34 +323,33 @@ The following example shows how to use the energy functions in
As was discussed above in the momenta functions, one first creates the system
by going through an identical procedure. ::
>>> from sympy import symbols
>>> from sympy.physics.mechanics import dynamicsymbols, ReferenceFrame, outer
>>> from sympy.physics.mechanics import RigidBody, Particle
>>> from sympy.physics.mechanics import kinetic_energy, potential_energy, Point
>>> m, M, l1, g, h, H = symbols('m M l1 g h H')
>>> omega = dynamicsymbols('omega')
>>> N = ReferenceFrame('N')
>>> O = Point('O')
>>> O.set_vel(N, 0 * N.x)
>>> Ac = O.locatenew('Ac', l1 * N.x)
>>> P = Ac.locatenew('P', l1 * N.x)
>>> a = ReferenceFrame('a')
>>> a.set_ang_vel(N, omega * N.z)
>>> Ac.v2pt_theory(O, N, a)
l1*omega*N.y
>>> P.v2pt_theory(O, N, a)
2*l1*omega*N.y
>>> Pa = Particle('Pa', P, m)
>>> I = outer(N.z, N.z)
>>> A = RigidBody('A', Ac, a, M, (I, Ac))
>> from sympy import symbols
>> from sympy.physics.mechanics import dynamicsymbols, ReferenceFrame, outer
>> from sympy.physics.mechanics import RigidBody, Particle, mechanics_printing
>> from symp.physics.mechanics import kinetic_energy, potential_energy, Point
>> mechanics_printing()
>> m, M, l1, g, h, H = symbols('m M l1 g h H')
>> omega = dynamicsymbols('omega')
>> N = ReferenceFrame('N')
>> O = Point('O')
>> O.set_vel(N, 0 * N.x)
>> Ac = O.locatenew('Ac', l1 * N.x)
>> P = Ac.locatenew('P', l1 * N.x)
>> a = ReferenceFrame('a')
>> a.set_ang_vel(N, omega * N.z)
>> Ac.v2pt_theory(O, N, a)
>> P.v2pt_theory(O, N, a)
>> Pa = Particle('Pa', P, m)
>> I = outer(N.z, N.z)
>> A = RigidBody('A', Ac, a, M, (I, Ac))
The user can then determine the kinetic energy of any number of entities of the
system: ::
>>> kinetic_energy(N, Pa)
2*l1**2*m*omega(t)**2
>>> kinetic_energy(N, Pa, A)
M*l1**2*omega(t)**2/2 + 2*l1**2*m*omega(t)**2 + omega(t)**2/2
>> kinetic_energy(N, Pa)
2*l1**2*m*q1d**2
>> kinetic_energy(N, Pa, A)
M*l1**2*q1d**2/2 + 2*l1**2*m*q1d**2 + q1d**2/2
It should be noted that the user can determine either kinetic energy relative
to any frame in :mod:`mechanics` as the user is allowed to specify the
@@ -366,15 +361,14 @@ every entity of the system using the :mod:`potential_energy` property. The
potential energy of any number of entities comprising the system can then be
determined: ::
>>> Pa.potential_energy = m * g * h
>>> A.potential_energy = M * g * H
>>> potential_energy(A, Pa)
>> Pa.potential_energy = m * g * h
>> A.potential_energy = M * g * H
>> potential_energy(A, Pa)
H*M*g + g*h*m
One can also determine the Lagrangian for this system: ::
>>> from sympy.physics.mechanics import Lagrangian
>>> Lagrangian(N, Pa, A)
-H*M*g + M*l1**2*omega(t)**2/2 - g*h*m + 2*l1**2*m*omega(t)**2 + omega(t)**2/2
>> Lagrangian(Pa, A)
-H*M*g + M*l1**2*q1d**2/2 - g*h*m + 2*l1**2*m*q1d**2 + q1d**2/2
Please refer to the docstrings to learn more about each function.
@@ -1,717 +0,0 @@
.. _sympy_mechanics_for_autolev_users:
=================================
SymPy Mechanics for Autolev Users
=================================
Introduction
------------
Autolev (now superseded by MotionGenesis) is a domain specific programming
language which is used for symbolic multibody dynamics. The SymPy mechanics
module now has enough power and functionality to be a fully featured symbolic
dynamics module. The PyDy package extends the SymPy output to the numerical
domain for simulation, analyses and visualization. Autolev and SymPy Mechanics have
a lot in common but there are also many differences between them.
This page shall expand upon their differences. It is meant to be a go-to
reference for Autolev users who want to transition to SymPy Mechanics.
It would be nice to have a basic understanding of SymPy and SymPy Mechanics before
going over this page.
If you are completely new to Python, you can check out the official
`Python Tutorial <https://docs.python.org/3/tutorial/>`_.
Check out the :ref:`SymPy Documentation <documentation>`, especially
the tutorial to get a feel for SymPy.
For an introduction to Multibody dynamics in Python, `this <https://www.youtube.com/watch?v=mdo2NYtA-xY&t=6950s>`_
lecture is very helpful.
You might also find the :ref:`Autolev Parser <autolev_parser>` which is
a part of SymPy to be helpful.
Some Key Differences
------------------------
+-----------------------------------+-----------------------------------+
| **Autolev** | **SymPy Mechanics** |
+===================================+===================================+
|| || |
| Autolev is a domain specific | SymPy is a library written in the |
| programming language designed to | general purpose language Python. |
| perform multibody dynamics. Since | Although Autolev's code is more |
| it is a language of its own, it | compact, SymPy (by virtue of being|
| has a very rigid language | an add on to Python) is more |
| specification. It predefines, | flexible. The users have more |
| assumes and computes | control over what they can do. For|
| many things based on the | example, one can create a class in|
| input code. Its code is a lot | their code for let's say a type of|
| cleaner and concise as a result of| rigibodies with common |
| this. | properties. |
| | The wide array of scientific |
| | Python libraries available is also|
| | a big plus. |
+-----------------------------------+-----------------------------------+
|| || |
| Autolev generates Matlab, C, or | SymPy generates numerical Python, |
| Fortran code from a small set of | C or Octave/Matlab code from a |
| symbolic mathematics. | large set of symbolic mathematics |
| | created with SymPy. It also builds|
| | on the popular scientific Python |
| | stack such as NumPy, SciPy, |
| | IPython, matplotlib, Cython and |
| | Theano. |
+-----------------------------------+-----------------------------------+
|| || |
| Autolev uses 1 (one) based | Python uses 0 (zero) based |
| indexing. The initial element of | indexing. The initial element of |
| a sequence is found using a[1]. | a sequence is found using a[0]. |
+-----------------------------------+-----------------------------------+
|| || |
| Autolev is case insensitive. | SymPy code being Python code is |
| | case sensitive. |
+-----------------------------------+-----------------------------------+
|| || |
| One can define their own commands | SymPy code is Python code, so one |
| in Autolev by making .R and .A | can define functions in their |
| files which can be used in their | code. This is a lot more |
| programs. | convenient. |
+-----------------------------------+-----------------------------------+
|| || |
| Autolev is proprietary. | SymPy is open source. |
+-----------------------------------+-----------------------------------+
Rough Autolev-SymPy Equivalents
----------------------------------
The tables below give rough equivalents for some common Autolev
expressions. **These are not exact equivalents**, but rather should be
taken as hints to get you going in the right direction. For more detail
read the built-in documentation on :ref:`SymPy vectors <physics_vector>`,
:ref:`SymPy mechanics <classical_mechanics>` and
`PyDy <https://www.pydy.org/documentation.html>`_ .
In the tables below, it is assumed that you have executed the following
commands in Python:
::
import sympy.physics.mechanics as me
import sympy as sm
Mathematical Equivalents
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-----------------------+-----------------------+-----------------------+
| **Autolev** | **SymPy** | **Notes** |
+=======================+=======================+=======================+
|| || || |
| ``Constants A, B`` | ``a, b = | Note that the names |
| | sm.symbols(‘a | of the symbols can be |
| | b’, real=True)`` | different from the |
| | | names of the |
| | | variables they are |
| | | assigned to. We can |
| | | define ``a, b = |
| | | symbols(‘b a’)`` but |
| | | its good practice to |
| | | follow the |
| | | convention. |
+-----------------------+-----------------------+-----------------------+
|| || || |
| ``Constants C+`` | ``c = sm.symbols(‘c’, | Refer to SymPy |
| | real=True, | :ref:`assumptions |
| | nonnegative=True)`` | <assumptions_module>` |
| | | for more information. |
+-----------------------+-----------------------+-----------------------+
|| || || |
| ``Constants D-`` | ``d = sm.symbols(‘d’, | |
| | real=True, | |
| | nonpositive=True)`` | |
+-----------------------+-----------------------+-----------------------+
|| || || |
| ``Constants K{4}`` | ``k1, k2, k3, k4 = | |
| | sm.symbols('k1 k2 k3 | |
| | k4', real=True)`` | |
+-----------------------+-----------------------+-----------------------+
|| || || |
| ``Constants a{2:4}`` | ``a2, a3, a4 = | |
| | sm.symbols('a2 a3 a4',| |
| | real=True)`` | |
+-----------------------+-----------------------+-----------------------+
|| || || |
| ``Constants | ``b11, b12, b21, b22 =| |
| b{1:2, 1:2}`` | sm.symbols('b11 b12 | |
| | b21 b22', real=True)``| |
+-----------------------+-----------------------+-----------------------+
|| || || |
| ``Specified Phi`` | ``phi = | |
| | me.dynamicsymbols(‘phi| |
| | ')`` | |
+-----------------------+-----------------------+-----------------------+
|| || || |
| ``Variables q, s`` | ``q, s = | |
| | me.dynamicsymbols(q, | |
| | s)`` | |
+-----------------------+-----------------------+-----------------------+
| ``Variables x’’`` | ``x = | |
| | me.dynamicsymbols(‘x’ | |
| | )`` | |
| | | |
| | ``xd = | |
| | me.dynamicsymbols(‘x’ | |
| | , 1)`` | |
| | | |
| | ``xd2 = | |
| | me.dynamicsymbols(‘x’ | |
| | , 2)`` | |
+-----------------------+-----------------------+-----------------------+
| ``Variables y{2}’`` | ``y1 = | |
| | me.dynamicsymbols(‘y1’| |
| | )`` | |
| | | |
| | ``y2 = | |
| | me.dynamicsymbols(‘y2’| |
| | )`` | |
| | | |
| | ``y1d = | |
| | me.dynamicsymbols(‘y1’| |
| | , 1)`` | |
| | | |
| | ``y2d = | |
| | me.dynamicsymbols(‘y2'| |
| | , 1)`` | |
+-----------------------+-----------------------+-----------------------+
| ``MotionVariables | ``u1 = | SymPy doesn’t |
| u{2}`` | me.dynamicsymbols(‘u1’| differentiate between |
| | )`` | variables, |
| | | motionvariables and |
| | ``u2 = | specifieds during |
| | me.dynamicsymbols('u2'| declaration. Instead, |
| | )`` | it takes different |
| | | lists of these as |
| | | parameters in objects |
| | | like the KanesMethod. |
+-----------------------+-----------------------+-----------------------+
| ``Imaginary j`` | ``j = sm.I`` | I is a sympy object |
| | | which stands for the |
| | | imaginary unit. One |
| | | can define complex |
| | | numbers using it. |
| | | |
| | | ``z = x + I*y`` |
| | | |
| | | where x, y and z are |
| | | symbols. |
+-----------------------+-----------------------+-----------------------+
| ``Tina = 2*pi`` | ``tina = 2*sm.pi`` | Using ``.evalf()`` |
| | | will result in the |
| | ``tina = | numeric value. |
| | tina.evalf()`` | |
| | | |
| ``s = u*t + a*t^2/2`` | ``t = | |
| | me.dynamicsymbols._t``| |
| | | |
| | ``s = u*t + a*t**2/2``| |
+-----------------------+-----------------------+-----------------------+
|| || || |
| ``abs(x)^3 + sin(x)^2 | ``sm.abs(x)**3 | |
| + acos(x)`` | + sm.sin(x)**2 + | |
| | sm.acos(x)`` | |
+-----------------------+-----------------------+-----------------------+
| ``E = (x+2*y)^2 + | ``E = (x+2*y)**2 + | For more information |
| 3*(7+x)*(x+y)`` | 3*(7+x)*(x+y)`` | refer to |
| | | :ref:`simplification. |
| ``Expand(E)`` | ``sm.expand(E)`` | <tutorial-simplify>` |
| | | |
| ``Factor(E, x)`` | ``sm.horner(E, | |
| | wrt=x)`` | |
| | | |
| ``Coef(y, x)`` | ``y.coeff(x)`` | These SymPy functions |
| | | do not work in place. |
| ``Replace(y, | ``y.subs({sm.sin(x): | They just return |
| sin(x)=3)`` | 3})`` | expressions. If you |
| | | want to overwrite the |
| ``Exclude(E,x)`` | ``e.collect(x).coeff( | original expression |
| | x, 0)`` | you would have to do |
| | | something like: |
| ``Include(E,x)`` | ``e.collect(x).coeff( | |
| | x, 1)`` | ``y = |
| | | y.subs({sm.sin(x): |
| ``Arrange(E,2,y)`` | ``e.collect(y)`` | 3})`` |
+-----------------------+-----------------------+-----------------------+
| ``Dy = D(E, y)`` | ``E.diff(y)`` | For more information |
| | | refer to |
| ``Dt = Dt(E)`` | ``E.diff( | :ref:`calculus. |
| | me.dynamicsymbols._t | <calculus>` |
| | )`` | |
| | | |
| | Works if the | |
| | expression is made up | |
| | of dynamicsymbols. | |
| ``Dt2 = Dt(V, A)`` | | |
| where V is a vector | ``dt2 = v.dt(A)`` | |
| and A is a frame | | |
| | | |
| ``Dy2 = D(V, y, A)`` | ``dy2 = v.diff(y, A)``| |
| | | |
+-----------------------+-----------------------+-----------------------+
| ``E = COS(X*Y)`` | ``e = sm.cos(x*y)`` | For more information |
| | | refer to :ref:`series.|
| ``TY = Taylor(E, | ``b = e.series(x, 0, | <series_expansions>` |
| 0:2, x=0, y=0)`` | 2).removeO().series(y,| |
| | 0, 2).removeO()`` | |
| | | |
+-----------------------+-----------------------+-----------------------+
| ``F = Evaluate(E, | ``E.subs([(x, a), (y, | |
| x=a, y=2)`` | 2)])`` | |
| | | |
| | To get floating point | |
| | numbers from numerical| |
| | expressions use | |
| | ``.evalf()`` | |
| | | |
| | ``E.evalf((a + | |
| | sm.pi).subs({a: 3}))``| |
+-----------------------+-----------------------+-----------------------+
| ``P = Polynomial([a, | ``p = | For more information |
| b, c], x)`` | sm.Poly(sm.Matrix([a, | refer to |
| | b, c]).reshape(1, 3), | :ref:`polys. |
| | x)`` | <polys-reference>` |
+-----------------------+-----------------------+-----------------------+
| ``Roots(Polynomial( | ``sm.solve( | For more information |
| a*x^2 + b*x + c, x, | sm.Poly(a*x**2 + | refer to |
| 2)`` | b*x + c))`` | :ref:`solvers`. |
| | | |
| ``Roots([1;2;3])`` | ``sm.solve(sm.Poly( | For numerical |
| | sm.Matrix([1,2,3]). | computation related |
| | reshape(3, 1), x), | to polynomials and |
| | x)`` | roots refer to |
| | | `mpmath/calculus. <htt|
| | | p://docs.s |
| | | ympy.org/0.7.6/module |
| | | s/mpmath/calculus/pol |
| | | ynomials.html>`_ |
+-----------------------+-----------------------+-----------------------+
| ``Solve(A, x1, x2)`` | ``sm.linsolve(A, | For more information |
| | (x1, x2))`` | refer to |
| | | :ref:` |
| where A is an | where A is an | solvers/solveset. |
| augmented matrix that | augmented matrix | <solveset>` |
| represents the linear | | |
| equations and x1, x2 | | |
| are the variables to | | For non linear solvers|
| solve for. | | refer to |
| | | ``nonlinsolve`` and |
| | | ``nsolve`` in |
| | | :ref:`solvers. |
| | | <solvers>` |
+-----------------------+-----------------------+-----------------------+
| ``RowMatrix = [1, 2, | ``row_matrix = | For more information |
| 3, 4]`` | sm.Matrix([[1],[2], | refer to |
| | [3],[4]])`` | :ref:`matrices. |
| | | <matrices>` |
| ``ColMatrix = [1; 2; | ``col_matrix = | |
| 3; 4]`` | sm.Matrix([1, 2, 3, | |
| | 4])`` | |
| | | |
| ``MO = [a, b; c, 0]`` | ``MO = sm.Matrix([[a, | |
| | b], [c, 0]])`` | |
| | | |
| ``MO[2, 2] := d`` | ``MO[1, 1] = d`` | |
| | | |
| ``A + B*C`` | ``A + B*C`` | |
| | | |
| ``Cols(A)`` | ``A.cols`` | |
| | | |
| ``Cols(A, 1)`` | ``A.col(0)`` | |
| | | |
| ``Rows(A)`` | ``A.rows`` | |
| | | |
| ``Rows(A, 1)`` | ``A.row(0)`` | |
| | | |
| ``Det(A)`` | ``M.det()`` | |
| | | |
| ``Element(A, 2, 3)`` | ``M[2, 3]`` | |
| | | |
| ``Inv(A)`` | ``M**-1`` | |
| | | |
| ``Trace(A)`` | ``sm.trace(A)`` | |
| | | |
| ``Transpose(A)`` | ``A.T`` | |
| | | |
| ``Diagmat(4, 1)`` | ``sm.diag(1,1,1,1)`` | |
| | | |
| ``Eig(A)`` | ``A.eigenvals()`` | |
| | | |
| ``Eig(A, EigVal, | ``eigval = | |
| EigVec)`` | A.eigenvals()`` | |
| | | |
| | ``eigvec = | |
| | A.eigenvects()`` | |
+-----------------------+-----------------------+-----------------------+
Physical Equivalents
~~~~~~~~~~~~~~~~~~~~~~~~
+-----------------------+-----------------------+-----------------------+
| **Autolev** | **SymPy** | **Notes** |
+=======================+=======================+=======================+
| ``Bodies A`` | ``m =sm.symbols(‘m’)``| The 4th and 5th |
| | | arguments are for the |
| Declares A, its | ``Ao = | mass and inertia. |
| masscenter Ao, and | sm.symbols(‘Ao’)`` | These are specified |
| orthonormal vectors | | after the declaration |
| A1>, A2> and A3> | ``Af = | in Autolev. |
| fixed in A. | me.ReferenceFrame(‘Af’| |
| | )`` | |
| | | |
| | ``I = | One can pass a dummy |
| | me.outer(Af.x,Af.x)`` | for the parameters |
| | | and use setters |
| | ``P = me.Point(‘P’)`` | ``A.mass = \_`` and |
| | | ``A.inertia = \_`` to |
| | ``A =me.RigidBody(‘A’,| set them later. |
| | Ao, Af, m, (I, P))`` | |
| | | |
| | Af.x, Af.y and Af.z | For more information |
| | are equivalent to | refer to |
| | A1>, A2> and A3>. | :ref:`mechanics/masses|
| | | .<masses>` |
+-----------------------+-----------------------+-----------------------+
| ``Frames A`` | ``A = | For more information |
| | me.ReferenceFrame(‘A’ | refer to |
| ``V1> = | )`` | :ref:`physics/vectors.|
| X1*A1> + X2*A2>`` | | <matrices>` |
| | ``v1 = | |
| | x1*A.x + x2*A.y`` | |
+-----------------------+-----------------------+-----------------------+
| ``Newtonian N`` | ``N = | SymPy doesn’t specify |
| | me.ReferenceFrame(‘N’ | that a frame is |
| | )`` | inertial during |
| | | declaration. Many |
| | | functions such as |
| | | ``set_ang_vel()`` take|
| | | the inertial |
| | | reference frame as a |
| | | parameter. |
+-----------------------+-----------------------+-----------------------+
| ``Particles C`` | ``m = | The 2nd and 3rd |
| | sm.symbols(‘m’)`` | arguments are for the |
| | | point and mass. In |
| | ``Po = | Autolev, these are |
| | me.Point(‘Po’)`` | specified after the |
| | | declaration. |
| | ``C = me.Particle(‘C’,| |
| | Po, m)`` | One can pass a dummy |
| | | and use setters |
| | | (``A.point = \_`` and |
| | | ``A.mass = \_``) to |
| | | set them later. |
+-----------------------+-----------------------+-----------------------+
| ``Points P, Q`` | ``P = me.Point(‘P’)`` | |
| | | |
| | ``Q = me.Point(‘Q’)`` | |
+-----------------------+-----------------------+-----------------------+
| ``Mass B=mB`` | ``mB = symbols(‘mB’)``| |
| | | |
| | ``B.mass = mB`` | |
+-----------------------+-----------------------+-----------------------+
| ``Inertia B, I1, I2, | ``I = me.inertia(Bf, | For more information |
| I3, I12, I23, I31`` | i1, i2, i3, i12, i23, | refer to the |
| | i31)`` | :ref:`mechanics api. |
| | | <part_bod>` |
| | ``B.inertia = (I, P)``| |
| | where B is a | |
| | rigidbody, Bf is the | |
| | related frame and P is| |
| | the center of mass of | |
| | B. | |
| | | |
| | Inertia dyadics can | |
| | also be formed using | |
| | vector outer products.| |
| | | |
| | ``I = | |
| | me.outer(N.x, N.x)`` | |
+-----------------------+-----------------------+-----------------------+
| ``vec> = P_O_Q>/L`` | ``vec = | For more information |
| | (Qo.pos_from(O))/L`` | refer to |
| ``vec> = | | :ref:`physics/vectors.|
| u1*N1> + u2*N2>`` | ``vec = | <physics_vector>` |
| | u1*N.x + u2*N.y`` | |
| ``Cross(a>, b>)`` | | |
| | ``cross(a, b)`` | |
| ``Dot(a>, b>)`` | | |
| | ``dot(a, b)`` | |
| ``Mag(v>)`` | | |
| | ``v.magnitude()`` | |
| ``Unitvec(v>)`` | | |
| | ``v.normalize()`` | |
| | | |
| ``DYAD>> = 3*A1>*A1> +| ``dyad = | |
| A2>*A2> + 2*A3>*A3>`` | 3*me.outer(a.x | |
| | ,a.x) + me.outer(a.y, | |
| | a.y) + 2*me.outer(a.z | |
| | ,a.z)`` | |
+-----------------------+-----------------------+-----------------------+
| ``P_O_Q> = LA*A1>`` | ``Q.point = | For more information |
| | O.locatenew(‘Qo’, | refer to the |
| | LA*A.x)`` | :ref:`kinematics api. |
| | | <kinematics>` |
| ``P_P_Q> = LA*A1>`` | where A is a | |
| | reference frame. | |
| | | |
| | ``Q.point = | |
| | P.point.locatenew(‘Qo | All these vector and |
| | ’, | kinematic functions |
| | LA*A.x)`` | are to be used on |
| | | ``Point`` objects and |
| | | not ``Particle`` |
| | | objects so ``.point`` |
| | | must be used for |
| | | particles. |
+-----------------------+-----------------------+-----------------------+
| ``V_O_N> = u3*N.1> + | ``O.set_vel(N, u1*N.x | The getter would be |
| u4*N.2>`` | + u2*N.y)`` | ``O.vel(N)``. |
| | | |
| ``Partials(V_O_N>, | ``O.partial_velocity(N| |
| u3)`` | , u3)`` | |
+-----------------------+-----------------------+-----------------------+
| ``A_O_N> = 0>`` | ``O.set_acc(N, 0)`` | The getter would be |
| | | ``O.acc(N)``. |
| Acceleration of point | | |
| O in reference frame | | |
| N. | | |
+-----------------------+-----------------------+-----------------------+
| ``W_B_N> = qB’*B3>`` | ``B.set_ang_vel(N, | The getter would be |
| | qBd*Bf.z)`` | ``B.ang_vel_in(N)``. |
| Angular velocity of | | |
| body B in reference | where Bf is the frame | |
| frame F. | associated with the | |
| | body B. | |
+-----------------------+-----------------------+-----------------------+
| ``ALF_B_N> =Dt(W_B_N>,| ``B.set_ang_acc(N, | The getter would be |
| N)`` | diff(B.ang_vel_in(N) | ``B.ang_acc_in(N)``. |
| | )`` | |
| Angular acceleration | | |
| of body B in | | |
| reference frame N. | | |
+-----------------------+-----------------------+-----------------------+
| ``Force_O> = F1*N1> + | In SymPy one should | |
| F2*N2>`` | have a list which | |
| | contains all the | |
| ``Torque_A> = | forces and torques. | |
| -c*qA’*A3>`` | | |
| | ``fL.append((O, f1*N.x| |
| | + f2*N.y))`` | |
| | | |
| | where fL is the force | |
| | list. | |
| | | |
| | ``fl.append((A, | |
| | -c*qAd*A.z))`` | |
+-----------------------+-----------------------+-----------------------+
| ``A_B = M`` | ``B.orient(A, 'DCM', | |
| where M is a matrix | M)`` where M is a | |
| and A, B are frames. | SymPy Matrix. | |
| | | |
| ``D = A_B*2 + 1`` | ``D = A.dcm(B)*2 + 1``| |
+-----------------------+-----------------------+-----------------------+
| ``CM(B)`` | ``B.masscenter`` | |
+-----------------------+-----------------------+-----------------------+
| ``Mass(A,B,C)`` | ``A.mass + B.mass + | |
| | C.mass`` | |
+-----------------------+-----------------------+-----------------------+
| ``V1pt(A,B,P,Q)`` | ``Q.v1pt_theory(P, A, | P and Q are assumed to|
| | B)`` | be ``Point`` objects |
| | | here. Remember to use |
| | | ``.point`` for |
| | | particles. |
+-----------------------+-----------------------+-----------------------+
| ``V2pts(A,B,P,Q)`` | ``Q.v2pt_theory(P, A, | |
| | B)`` | |
+-----------------------+-----------------------+-----------------------+
| ``A1pt(A,B,P,Q)`` | ``Q.a1pt_theory(P, A, | |
| | B)`` | |
+-----------------------+-----------------------+-----------------------+
| ``A2pts(A,B,P,Q)`` | ``Q.a2pt_theory(P, A, | |
| | B)`` | |
+-----------------------+-----------------------+-----------------------+
| ``Angvel(A,B)`` | ``B.ang_vel_in(A)`` | |
+-----------------------+-----------------------+-----------------------+
| ``Simprot(A, B, 1, | ``B.orient(A, ‘Axis’, | |
| qA)`` | qA, A.x)`` | |
+-----------------------+-----------------------+-----------------------+
| ``Gravity(G*N1>)`` | ``fL.extend(gravity( | In SymPy we must use a|
| | g*N.x, P1, P2, ...))``| forceList (here fL) |
| | | which contains tuples |
| | | of the form ``(point, |
| | | force_vector)``. This |
| | | is passed to the |
| | | ``kanes_equations()`` |
| | | method of the |
| | | KanesMethod object. |
+-----------------------+-----------------------+-----------------------+
| ``CM(O,P1,R)`` | ``me.functions. | |
| | center_of_mass(o, p1, | |
| | r)`` | |
+-----------------------+-----------------------+-----------------------+
| ``Force(P/Q, v>)`` | ``fL.append((P, -1*v),| |
| | (Q, v))`` | |
+-----------------------+-----------------------+-----------------------+
| ``Torque(A/B, v>)`` | ``fL.append((A, -1*v),| |
| | (B, v))`` | |
+-----------------------+-----------------------+-----------------------+
| ``Kindiffs(A, B ...)``| ``KM.kindiffdict()`` | |
+-----------------------+-----------------------+-----------------------+
| ``Momentum(option)`` | ``linear_momentum(N, | |
| | B1, B2 ...)`` | |
| | | |
| | reference frame | |
| | followed by one or | |
| | more bodies | |
| | | |
| | ``angular_momentum(O, | |
| | N, B1, B2 ...)`` | |
| | | |
| | point, reference | |
| | frame followed by one | |
| | or more bodies | |
+-----------------------+-----------------------+-----------------------+
| ``KE()`` | ``kinetic_energy(N, | |
| | B1, B2 ...)`` | |
| | | |
| | reference frame | |
| | followed by one or | |
| | more bodies | |
+-----------------------+-----------------------+-----------------------+
| ``Constrain(...)`` | ``velocity_constraints| For more details |
| | = [...]`` | refer to |
| | | :ref:`mechanics/kane |
| | ``u_dependent = | <kane_method>` and |
| | [...]`` | the :ref:`kane api. |
| | | <kane_lagrange>` |
| | ``u_auxiliary = | |
| | [...]`` | |
| | | |
| | These lists are | |
| | passed to the | |
| | KanesMethod object. | |
+-----------------------+-----------------------+-----------------------+
| ``Fr()`` | ``KM = KanesMethod(f, | For more details |
| ``FrStar()`` | q_ind, u_ind, kd_eqs, | refer to |
| | q_dependent, configura| :ref:`mechanics/kane |
| | tion_constraints, u_de| <kane_method>` and |
| | pendent, velocity_cons| the :ref:`kane api. |
| | traints, acceleration_| <kane_lagrange>` |
| | constraints, u_auxilia| |
| | ry)`` | |
| | | |
| | The KanesMethod | |
| | object takes a | |
| | reference frame | |
| | followed by multiple | |
| | lists as arguments. | |
| | | |
| | ``(fr, frstar) = | |
| | KM.kanes_equations(fL,| |
| | bL)`` where fL and bL | |
| | are lists of forces | |
| | and bodies | |
| | respectively. | |
+-----------------------+-----------------------+-----------------------+
Numerical Evaluation and Visualization
----------------------------------------
Autolev’s CODE Option() command allows one to generate Matlab, C, or
Fortran code for numerical evaluation and visualization. Option can be
Dynamics, ODE, Nonlinear or Algebraic.
Numerical evaluation for dynamics can be achieved using PyDy. One can
pass in the KanesMethod object to the System class along with the values
for the constants, specifieds, initial conditions and time steps. The
equations of motion can then be integrated. The plotting is achieved
using matlplotlib. Here is an example from the `PyDy Documentation <https://www.pydy.org/documentation.html>`_
on how it is done::
from numpy import array, linspace, sin
from pydy.system import System
sys = System(kane,
constants = {mass: 1.0, stiffness: 1.0,
damping: 0.2, gravity: 9.8},
specifieds = {force: lambda x, t: sin(t)},
initial_conditions = {position: 0.1, speed:-1.0},
times = linspace(0.0, 10.0, 1000))
y = sys.integrate()
import matplotlib.pyplot as plt
plt.plot(sys.times, y)
plt.legend((str(position), str(speed)))
plt.show()
For information on all the things PyDy can accomplish refer to the
`PyDy Documentation <https://www.pydy.org/documentation.html>`_.
The tools in the PyDy workflow are :
- `SymPy <https://sympy.org>`_: SymPy is a Python library for
symbolic computation. It provides computer algebra capabilities
either as a standalone application, as a library to other
applications, or live on the web as SymPy Live or SymPy Gamma.
- `NumPy <https://www.numpy.org/>`_: NumPy is a library for the
Python programming language, adding support for large,
multi-dimensional arrays and matrices, along with a large
collection of high-level mathematical functions to operate on
these arrays.
- `SciPy <https://www.scipy.org/>`_: SciPy is an open source
Python library used for scientific computing and technical
computing. SciPy contains modules for optimization, linear
algebra, integration, interpolation, special functions, FFT,
signal and image processing, ODE solvers and other tasks common
in science and engineering.
- `IPython <https://ipython.org/>`_: IPython is a command shell
for interactive computing in multiple programming languages,
originally developed for the Python programming language, that
offers introspection, rich media, shell syntax, tab completion,
and history.
- `Theano <http://deeplearning.net/software/theano/>`_: Theano is
a numerical computation library for Python. In Theano,
computations are expressed using a NumPy-esque syntax and
compiled to run efficiently on either CPU or GPU architectures
- `Cython <http://cython.org/>`_: Cython is a superset of the
Python programming language, designed to give C-like performance
with code that is mostly written in Python. Cython is a compiled
language that generates CPython extension modules.
- `matplotlib <https://matplotlib.org/>`_: matplotlib is a
plotting library for the Python programming language and its
numerical mathematics extension NumPy.
One will be able to write code equivalent to the Matlab, C or Fortran
code generated by Autolev using these scientific computing tools. It is
recommended to go over these modules to gain an understanding of
scientific computing with Python.
Links
----------
:ref:`SymPy Tutorial <tutorial>`
:ref:`SymPy Documentation <documentation>`
:ref:`SymPy Physics Vector
Documentation <physics_vector>`
:ref:`SymPy Mechanics
Documentation <classical_mechanics>`
`PyDy Documentation <https://www.pydy.org/documentation.html>`_
`MultiBody Dynamics with Python <https://www.youtube.com/watch?v=mdo2NYtA-xY>`_
+9 -22
View File
@@ -2,14 +2,14 @@
Examples
========
In the following sections we give few examples of what can be done with this
In the following sections we give few examples of what can be do with this
module.
Dimensional analysis
====================
We will start from Newton's second law
We will start from the second Newton's law
.. math::
m a = F
@@ -81,39 +81,26 @@ variables (taken from Wikipedia). The result should be 224.701 days.
>>> from sympy.physics.units import day, gravitational_constant as G
>>> from sympy.physics.units import meter, kilogram
>>> T = symbols("T")
>>> a = Quantity("venus_a")
Specify the dimension and scale in SI units:
>>> a.set_dimension(length, "SI")
>>> a.set_scale_factor(108208000e3*meter, "SI")
Add the solar mass as quantity:
>>> M = Quantity("solar_mass")
>>> M.set_dimension(mass, "SI")
>>> M.set_scale_factor(1.9891e30*kilogram, "SI")
Now Kepler's law:
>>> a = Quantity("venus_a", length, 108208000e3*meter)
>>> M = Quantity("solar_mass", mass, 1.9891e30*kilogram)
>>> eq = Eq(T**2 / a**3, 4*pi**2 / G / M)
>>> eq
Eq(T**2/venus_a**3, 4*pi**2/(gravitational_constant*solar_mass))
>>> q = solve(eq, T)[1]
>>> q
2*pi*venus_a**(3/2)/(sqrt(gravitational_constant)*sqrt(solar_mass))
6.28318530717959*venus_a**(3/2)/(sqrt(gravitational_constant)*sqrt(solar_mass))
To convert to days, use the ``convert_to`` function (and possibly approximate
the outcoming result):
the outcoming result:
>>> from sympy.physics.units import convert_to
>>> convert_to(q, day)
71.5112118495813*pi*day
2.15992161980729e-7*sqrt(1081898088255574765)*day
>>> convert_to(q, day).n()
224.659097795948*day
224.662800523082*day
We could also have the solar mass and the day as units coming from the
astrophysical system, but we wanted to show how to create a unit that one needs.
astrophysical system, but I wanted to show how to create a unit that one needs.
We can see in this example that intermediate dimensions can be ill-defined,
such as sqrt(G), but one should check that the final result - when all

Some files were not shown because too many files have changed in this diff Show More