├── .codespell-ignore-words ├── .codespellrc ├── .github ├── dependabot.yml └── workflows │ └── main.yml ├── .gitignore ├── CHANGES ├── README.md ├── ad ├── CREDITS ├── Matplotlib_logo.svg ├── python_science.fodp └── python_science.pdf ├── bulletin.txt ├── content ├── 01-python │ ├── NOTE │ ├── VARDEN-tests.ini │ ├── basics.md │ ├── functions-classes.md │ ├── installing.md │ ├── misc.md │ ├── myprofile.py │ ├── paradigms.png │ ├── python-io.ipynb │ ├── python.md │ ├── python.png │ ├── scipy.png │ ├── shopping.csv │ ├── shopping.fods │ ├── shopping_cart.py │ ├── test.txt │ ├── tic_tac_toe.py │ ├── using.md │ ├── vector2d.py │ ├── w1-jupyter.ipynb │ ├── w1-python-datatypes.ipynb │ ├── w2-python-advanced-datatypes.ipynb │ ├── w2-python-control-flow.ipynb │ ├── w2-python-exercises.ipynb │ ├── w3-python-exceptions.ipynb │ ├── w3-python-exercises.ipynb │ ├── w3-python-functions.ipynb │ ├── w4-python-classes.ipynb │ ├── w4-python-exercises.ipynb │ ├── w4-python-modules.ipynb │ └── w5-python-more-examples.ipynb ├── 02-numpy │ ├── numpy-advanced.ipynb │ ├── numpy-basics.ipynb │ ├── numpy-exercises.ipynb │ ├── numpy.md │ ├── row_column_major.png │ ├── sample.txt │ └── slicing.png ├── 03-practices │ ├── git-single.md │ ├── git.png │ ├── git.txt │ └── python-style.ipynb ├── 04-matplotlib │ ├── NOTES │ ├── anatomy1.png │ ├── ipyvolume-example.ipynb │ ├── matplotlib-basics.ipynb │ ├── matplotlib-exercises.ipynb │ ├── matplotlib.md │ ├── matplotlib.pdf │ ├── test.png │ └── test1.exact.128.out ├── 05-scipy │ ├── bisection.avi │ ├── condition-example.py │ ├── integrals.py │ ├── newton.avi │ ├── orbit_setup.png │ ├── pendulum_answer.py │ ├── pendulum_fft.py │ ├── rectangle.png │ ├── rk4_Euler.png │ ├── rk4_final.png │ ├── rk4_initial.png │ ├── rk4_k1.png │ ├── rk4_k2.png │ ├── rk4_k3.png │ ├── rk4_k4.png │ ├── rk4_plot.py │ ├── scipy-basics-2.ipynb │ ├── scipy-basics.ipynb │ ├── scipy-exercises-2.ipynb │ ├── scipy-exercises.ipynb │ ├── scipy.md │ ├── scipy.png │ ├── simpsons.png │ └── trapezoid.png ├── 06-sympy │ ├── sympy-examples.ipynb │ ├── sympy-exercises.ipynb │ └── sympy.md ├── 07-pandas │ ├── exercises.txt │ ├── ideas.txt │ ├── pandas-babynames.ipynb │ ├── pandas-experiments.ipynb │ ├── pandas-intro.ipynb │ ├── pandas-worldbank.ipynb │ ├── pandas_solutions.txt │ └── sample.csv ├── 09-packages │ ├── NOTES │ ├── argparse_example.py │ ├── packaging.pdf │ ├── python-arguments.md │ ├── python-modules.md │ ├── python-more-modules.md │ ├── python-packages.md │ ├── python-tools.md │ ├── python_environment.png │ └── test.png ├── 10-testing │ ├── more-pytest.md │ ├── notes.txt │ ├── pytest │ ├── pytest.md │ ├── real-world-example.md │ ├── testing.fodp │ ├── testing.md │ └── unit_integration.gif ├── 11-machine-learning │ ├── README │ ├── gradient-descent.ipynb │ ├── ideas.txt │ ├── keras-clustering.ipynb │ ├── keras-mnist.ipynb │ ├── machine-learning-basics.ipynb │ ├── machine-learning-libraries.md │ ├── machine-learning.md │ ├── model.png │ ├── neural-net-basics.md │ ├── neural-net-derivation.md │ ├── neural-net-hidden.md │ ├── neural-net-improvements.md │ ├── nn_fig.png │ ├── nn_fig.py │ ├── nn_fig2.png │ ├── nn_fig_hidden.png │ ├── sigmoid.png │ └── sigmoid.py ├── 12-extensions │ ├── extensions-example.md │ ├── extensions-overview.md │ └── test.png ├── CHANGES ├── Introduction.md ├── NOTES ├── _config.yml ├── _static │ └── myfile.css ├── _toc.yml └── git │ ├── distributed_version_control.png │ ├── git-branches.md │ ├── git-remotes.md │ ├── git.md │ ├── github-clone.png │ ├── github-copy-ssh.png │ ├── github-create.png │ ├── github-fork.png │ ├── github-new.png │ ├── github-pr.png │ ├── github-pr2.png │ ├── github-workflow.odg │ ├── github-workflow.pdf │ ├── github-workflow.png │ ├── github.md │ ├── pull-requests.md │ └── version-control.md ├── docs ├── .nojekyll ├── LICENSE.txt ├── assets │ ├── css │ │ ├── font-awesome.min.css │ │ ├── ie9.css │ │ ├── images │ │ │ ├── 0101_banner.png │ │ │ ├── overlay.png │ │ │ └── rt_1.5e7_clean2.png │ │ └── main.css │ ├── fonts │ │ ├── FontAwesome.otf │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.svg │ │ ├── fontawesome-webfont.ttf │ │ ├── fontawesome-webfont.woff │ │ └── fontawesome-webfont.woff2 │ └── js │ │ ├── ie │ │ ├── PIE.htc │ │ ├── html5shiv.js │ │ └── respond.min.js │ │ ├── jquery.min.js │ │ ├── main.js │ │ ├── skel.min.js │ │ └── util.js ├── images │ ├── python.png │ └── rt_1.5e7_clean2.png ├── index.html └── old │ ├── class.css │ ├── examples │ ├── C-API │ │ ├── numpy-ex.c │ │ ├── setup.py │ │ └── test-C-API.py │ ├── Cython │ │ ├── setup.py │ │ ├── square.pyx │ │ └── test_cy.py │ ├── argparse_example.py │ ├── ctypes │ │ ├── Makefile │ │ ├── cfunc_multid.c │ │ └── test-ctypes.py │ ├── f2py │ │ ├── Makefile │ │ ├── numpy_in_f.f90 │ │ └── test_f2py.py │ ├── gauss-test.py │ ├── gauss.py │ ├── getopt_example.py │ ├── githash.py │ ├── matmul.f90 │ ├── matmul.py │ ├── mayavi-basic.py │ ├── mayavi-vector.py │ └── timing │ │ ├── Makefile │ │ ├── README │ │ ├── laplace.py │ │ ├── laplace_C.c │ │ ├── laplace_CAPI.c │ │ ├── laplace_cython.pyx │ │ ├── laplace_fortran.f90 │ │ └── setup.py │ ├── index.html │ ├── lectures │ ├── VARDEN-tests.ini │ ├── extensions.pdf │ ├── gui.pdf │ ├── matplotlib.pdf │ ├── mayavi.pdf │ ├── numpy.pdf │ ├── packaging.pdf │ ├── profile.py │ ├── python-practices.pdf │ ├── python.pdf │ ├── scipy.pdf │ ├── shopping.csv │ ├── test.png │ ├── test.txt │ ├── test1.exact.128.out │ └── testing.pdf │ └── python.png ├── examples ├── .gitignore ├── GUI │ ├── NOTES │ ├── event-example.py │ ├── fitter.py │ ├── fitter_theme.py │ ├── parse.py │ └── plotter.py ├── commandline │ └── argparse_example.py ├── extensions-old │ ├── C-API │ │ ├── README │ │ ├── numpy-ex.c │ │ ├── setup.py │ │ └── test-C-API.py │ ├── Cython │ │ ├── laplace │ │ │ ├── README │ │ │ ├── laplace.pyx │ │ │ ├── setup.py │ │ │ └── test_cy.py │ │ └── square │ │ │ ├── setup.py │ │ │ ├── square.pyx │ │ │ └── test_cy.py │ ├── ctypes │ │ ├── multi-d │ │ │ ├── Makefile │ │ │ ├── README │ │ │ ├── cfunc_multid.c │ │ │ ├── test-ctypes.py │ │ │ └── test_multid.py │ │ └── simple │ │ │ ├── Makefile │ │ │ ├── README │ │ │ ├── cfunc.c │ │ │ ├── numpy-example.py │ │ │ └── pointer-example.py │ ├── f2py │ │ ├── Makefile │ │ ├── numpy_in_f.f90 │ │ └── test_f2py.py │ └── timing │ │ ├── Makefile │ │ ├── README │ │ ├── laplace.py │ │ ├── laplace_C.c │ │ ├── laplace_CAPI.c │ │ ├── laplace_cython.pyx │ │ ├── laplace_fortran.f90 │ │ └── setup.py ├── extensions │ ├── cython │ │ ├── README │ │ ├── mandel.pyx │ │ ├── setup.py │ │ └── test_mandel.py │ ├── f2py │ │ ├── README │ │ ├── mandel.f90 │ │ └── test_mandel.py │ ├── numba │ │ ├── mandel.py │ │ └── test_mandel.py │ ├── pybind11 │ │ ├── README │ │ ├── contiguous │ │ │ ├── README │ │ │ ├── mandel.cpp │ │ │ └── test_mandel.py │ │ ├── mandel.cpp │ │ └── test_mandel.py │ ├── python-slow │ │ ├── mandel.py │ │ └── test_mandel.py │ └── python │ │ ├── mandel.py │ │ └── test_mandel.py ├── external │ ├── Popen │ │ └── githash.py │ └── filesystem │ │ └── backup-machine.py ├── h5py │ └── h5_example.py ├── linear-algebra │ ├── gaussian-elimination │ │ ├── gauss-test.py │ │ ├── gauss.py │ │ └── matmul.py │ └── tridiagonal │ │ └── lap.py ├── machine-learning │ ├── character_recognition │ │ ├── README │ │ ├── char_recognition.py │ │ ├── character_recognition.ipynb │ │ ├── nn_epochs.py │ │ ├── nn_hidden_size.py │ │ ├── nn_learning_rate.py │ │ ├── nn_training_size.py │ │ └── show_character.py │ ├── keras │ │ └── feed-forward │ │ │ ├── README.md │ │ │ └── feedforward_keras_mnist.py │ └── steepest_descent │ │ ├── min_2d_descent.png │ │ ├── min_2d_start.png │ │ └── steepest_descent.py ├── matplotlib │ └── fractal │ │ └── mandelbrot.py ├── mayavi │ ├── mayavi-basic.py │ └── mayavi-vector.py ├── modules │ └── simple │ │ └── my_module.py ├── numerical-basics │ └── overflow │ │ ├── overflow.f90 │ │ └── overflow.py ├── packaging │ ├── distutils │ │ └── foo │ │ │ ├── foo.py │ │ │ └── setup.py │ ├── example │ │ └── mytest │ │ │ ├── __init__.py │ │ │ ├── demo │ │ │ ├── __init__.py │ │ │ └── demo.py │ │ │ └── util │ │ │ ├── __init__.py │ │ │ └── msg.py │ ├── setuptools │ │ └── foo2 │ │ │ ├── foo2 │ │ │ ├── __init__.py │ │ │ └── foo.py │ │ │ └── setup.py │ └── single_file │ │ └── example.py ├── practices │ └── git │ │ └── working-with-github.txt ├── python-snippets │ ├── README │ ├── advanced │ │ ├── inheritance.ipynb │ │ ├── looplistdelete.post │ │ ├── mail.post │ │ ├── regex.post │ │ ├── regex.py │ │ └── zip.post │ ├── basics │ │ ├── class-example.py │ │ ├── escapesequences.post │ │ ├── functionfunction.post │ │ ├── in.post │ │ ├── shallowcopy.post │ │ ├── stringsmutable.post │ │ └── zip-ex.py │ ├── numpy │ │ ├── functionfunction.py │ │ └── simple-exercise.txt │ └── resources.txt ├── scipy │ ├── FFT │ │ ├── cleaned.png │ │ ├── convolve.py │ │ ├── gaussian.png │ │ ├── make_signal.py │ │ ├── signal.txt │ │ └── test.png │ └── ODEs │ │ └── chaotic_pendulum.py └── testing │ └── pytest │ ├── class │ └── test_class.py │ ├── fixtures │ ├── shopping_cart.py │ ├── test_item.py │ └── test_list.py │ ├── function_setup │ └── test_function_setup.py │ └── simple │ └── test_simple.py ├── other ├── 50-mayavi │ ├── NOTES │ └── mayavi.pdf ├── 60-GUI │ └── gui-notebook.ipynb ├── LectureNotebooks ├── projectile-motion.ipynb └── scientific-python-lectures-master │ ├── .gitignore │ ├── Lecture-0-Scientific-Computing-with-Python.ipynb │ ├── Lecture-1-Introduction-to-Python-Programming.ipynb │ ├── Lecture-2-Numpy.ipynb │ ├── Lecture-3-Scipy.ipynb │ ├── Lecture-4-Matplotlib.ipynb │ ├── Lecture-5-Sympy.ipynb │ ├── Lecture-6A-Fortran-and-C.ipynb │ ├── Lecture-6B-HPC.ipynb │ ├── Lecture-7-Revision-Control-Software.ipynb │ ├── README.md │ ├── cy_dcumsum.c │ ├── cy_dcumsum.pyx │ ├── dcumsum.f │ ├── dprod.f │ ├── dprod.pyf │ ├── filename.png │ ├── filename.svg │ ├── functions.c │ ├── functions.o │ ├── functions.py │ ├── hello.py │ ├── hellofortran.f │ ├── images │ ├── github-diff.png │ ├── github-project-page.png │ ├── gitk.png │ ├── ipython-notebook-screenshot.jpg │ ├── ipython-screenshot.jpg │ ├── optimizing-what-2.png │ ├── optimizing-what.png │ ├── python-screenshot.jpg │ ├── scientific-python-stack.png │ ├── scientific-python-stack.svg │ ├── spyder-screenshot.jpg │ ├── theory-experiment-computation.png │ └── theory-experiment-computation.svg │ ├── ipython-example.ipynb │ ├── run_hello_c.py │ ├── scripts │ ├── hello-world-in-swedish.py │ └── hello-world.py │ ├── setup.py │ └── stockholm_td_adj.dat ├── pyproject.toml ├── requirements.txt ├── syllabus ├── GNUmakefile ├── accessibility.sty └── syllabus.tex └── topics.txt /.codespell-ignore-words: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/.codespell-ignore-words -------------------------------------------------------------------------------- /.codespellrc: -------------------------------------------------------------------------------- 1 | [codespell] 2 | skip = .git,*.bib,*.ps,*.js,*.pdf,_build,*.fodp,*.fods 3 | ignore-words = .codespell-ignore-words 4 | 5 | 6 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # Dependabot configuration 2 | # ref: https://docs.github.com/en/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/configuration-options-for-dependency-updates 3 | version: 2 4 | updates: 5 | - package-ecosystem: "github-actions" 6 | directory: "/" 7 | schedule: 8 | interval: "weekly" 9 | 10 | - package-ecosystem: "pip" 11 | directory: "/" 12 | schedule: 13 | interval: "weekly" 14 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Publish JupyterBook to GitHub Pages 2 | 3 | on: 4 | push: # trigger build only when push to main 5 | branches: 6 | - main 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - uses: actions/checkout@v4 14 | - name: Set up Python 15 | uses: actions/setup-python@v5 16 | with: 17 | python-version: "3.11" 18 | cache: "pip" 19 | - name: Install Python dependencies 20 | run: | 21 | sudo apt-get install python3-pip graphviz 22 | pip install -r requirements.txt 23 | pip install ghp-import 24 | PATH="${PATH}:${HOME}/.local/bin" 25 | 26 | - name: Build book HTML 27 | run: | 28 | jupyter-book build ./content 29 | 30 | - name: Push _build/html to gh-pages 31 | run: | 32 | sudo chown -R $(whoami):$(whoami) . 33 | git config --global user.email "$GITHUB_ACTOR@users.noreply.github.com" 34 | git config --global user.name "$GITHUB_ACTOR" 35 | git remote set-url origin "https://$GITHUB_ACTOR:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY" 36 | 37 | ghp-import ./content/_build/html -f -p -n 38 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | *.aux 3 | *.pyc 4 | *~ 5 | 6 | .ipynb_checkpoints/ 7 | Untitled*.ipynb 8 | 9 | \#* 10 | 11 | syllabus.pdf 12 | syllabus.out 13 | 14 | .cache 15 | 16 | *egg-info 17 | 18 | .~lock* 19 | 20 | *.fodp 21 | 22 | _build 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python in Scientific Computing 2 | *lecture notes and IPython notebooks* 3 | 4 | These are the lecture notes and IPython notebooks used to teach the 5 | *Python for Scientific Computing* class at Stony Brook University. 6 | 7 | Feel free to fork this repository and make any changes you wish. 8 | Contributions are welcomed. 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /ad/CREDITS: -------------------------------------------------------------------------------- 1 | numbers business template from: 2 | http://www.presentationmagazine.com/numbers-business-template-310.htm 3 | -------------------------------------------------------------------------------- /ad/python_science.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/ad/python_science.pdf -------------------------------------------------------------------------------- /bulletin.txt: -------------------------------------------------------------------------------- 1 | Course Name: Python for Scientific Computing 2 | 3 | Credits: 0-1 4 | 5 | Description: 6 | 7 | Python has seen wide adoption in the scientific community for data 8 | analysis, simulation, prototyping, and visualization. It provides a 9 | simple, yet powerful means to build applications. This seminar 10 | introduces python and its use in scientific computing. Students will 11 | learn the standard python libraries for array manipulation, 12 | visualization, numerical analysis, and symbolic mathematics, as well 13 | as how to interface python with other languages, build applications, 14 | and good software engineering practices (including version control and 15 | testing). Students are encouraged to share examples from their 16 | discipline. 17 | 18 | -------------------------------------------------------------------------------- /content/01-python/NOTE: -------------------------------------------------------------------------------- 1 | -- use the pyro timer util to illustrate modules and classes 2 | -------------------------------------------------------------------------------- /content/01-python/VARDEN-tests.ini: -------------------------------------------------------------------------------- 1 | [main] 2 | boxLibDir = /home/regtester/RegTesting/BoxLib/ 3 | sourceDir = /home/regtester/RegTesting/VARDEN/ 4 | testTopDir = /home/regtester/RegTesting/rt-VARDEN/ 5 | webTopDir = /home/regtester/RegTesting/rt-VARDEN/web 6 | compareToolDir = /home/regtester/RegTesting/AmrPostprocessing/F_Src 7 | 8 | MAKE = make 9 | sourceTree = F_Src 10 | numMakeJobs = 8 11 | 12 | COMP = g++ 13 | FCOMP = gfortran 14 | 15 | # suiteName is the name prepended to all output directories 16 | suiteName = VARDEN 17 | 18 | reportActiveTestsOnly = 1 19 | 20 | # Add "GO UP" link at the top of the web page? 21 | goUpLink = 1 22 | 23 | 24 | # MPIcommand should use the placeholders: 25 | # @host@ to indicate where to put the hostname to run on 26 | # @nprocs@ to indicate where to put the number of processors 27 | # @command@ to indicate where to put the command to run 28 | # 29 | # only tests with useMPI = 1 will run in parallel 30 | # nprocs is problem dependent and specified in the individual problem 31 | # sections. 32 | 33 | #MPIcommand = mpiexec -host @host@ -n @nprocs@ @command@ 34 | MPIcommand = /usr/local/bin/mpiexec -n @nprocs@ @command@ 35 | MPIhost = 36 | 37 | # individual problems follow 38 | 39 | [bubble-2d] 40 | buildDir = varden/test 41 | inputFile = inputs_2d-regt 42 | dim = 2 43 | restartTest = 0 44 | useMPI = 1 45 | numprocs = 2 46 | useOMP = 0 47 | numthreads = 2 48 | compileTest = 0 49 | doVis = 0 50 | 51 | [bubble-3d] 52 | buildDir = varden/test 53 | inputFile = inputs_3d-regt 54 | dim = 3 55 | restartTest = 0 56 | useMPI = 1 57 | numprocs = 3 58 | useOMP = 1 59 | numthreads = 2 60 | compileTest = 0 61 | doVis = 0 62 | 63 | [bubble-restart] 64 | buildDir = varden/test 65 | inputFile = inputs-restart-regt 66 | dim = 3 67 | restartTest = 1 68 | restartFileNum = 4 69 | useMPI = 1 70 | numprocs = 3 71 | useOMP = 1 72 | numthreads = 2 73 | compileTest = 0 74 | doVis = 0 75 | -------------------------------------------------------------------------------- /content/01-python/basics.md: -------------------------------------------------------------------------------- 1 | # Python Basics 2 | 3 | The following references give helpful introductions to python: 4 | 5 | * The [official python tutorial](http://docs.python.org/3/tutorial/) 6 | 7 | * The [software carpentry python lessons](https://swcarpentry.github.io/python-novice-inflammation/) 8 | 9 | 10 | ## Practicing 11 | 12 | Some resources for practicing on your own: 13 | 14 | * [Code Academy python rack](http://www.codecademy.com/tracks/python): 15 | step-by-step tutorial through the basics of the language 16 | 17 | * [Project Euler](https://projecteuler.net/): 18 | a set of increasingly complex programming tasks to try out with 19 | python 20 | 21 | 22 | ## Online books: 23 | 24 | * [Think python](https://greenteapress.com/wp/think-python-3rd-edition/) 25 | 26 | * [Dive into Python](https://diveintopython3.net/) 27 | 28 | * [SciPy Lecture Notes](http://scipy-lectures.github.io/) 29 | 30 | * [Google's python class](https://developers.google.com/edu/python/) 31 | 32 | * more resources can be found at: http://pythonbooks.revolunet.com/ 33 | 34 | 35 | ## Domain-specific libraries 36 | 37 | * Astronomy: [AstroPy](http://astropy.org) 38 | 39 | * Atmospheric sciences: [PyAOS](https://pyaos.github.io/) 40 | 41 | * Biology: [Biopython](http://biopython.org/) 42 | 43 | * Ocean and marine sciences: [OceanPython](http://oceanpython.org/) 44 | 45 | * Psychology resources: [PyschoPy](http://www.psychopy.org/) 46 | 47 | * Quantum physics: [QuTiP](http://qutip.org/) 48 | 49 | * Solar physics: [SunPy](http://sunpy.org/) 50 | 51 | 52 | -------------------------------------------------------------------------------- /content/01-python/functions-classes.md: -------------------------------------------------------------------------------- 1 | # Functions and Classes 2 | 3 | Functions and classes are the building blocks of complex programs. 4 | These allow you to organize your code into logical units that can 5 | reused. 6 | -------------------------------------------------------------------------------- /content/01-python/installing.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | This class will introduce the basics of the python programming 4 | language and the libraries used for scientific computing. 5 | 6 | ```{tip} 7 | To get the most from this class, you should work on your own laptop. That 8 | way you practice using python and the scientific libraries on the in the 9 | environment you are most comfortable with. 10 | ``` 11 | 12 | ## Getting python 13 | 14 | You will want to install python and the associated libraries on your 15 | laptop that you can bring to the seminar. 16 | 17 | On Linux machines, you probably already have python and you can get 18 | the needed libraries through your system package manager. 19 | 20 | For Mac and Windows, I recommend the free Anaconda distribution: 21 | 22 | https://www.anaconda.com/products/individual 23 | 24 | This will install everything that you need. 25 | 26 | ```{tip} 27 | If you have trouble getting a local install working, most of the class 28 | material will work automatically in the cloud, either on 29 | [binder](https://mybinder.org/) or [google 30 | colab](https://research.google.com/colaboratory/). 31 | ``` 32 | 33 | If you have python successfully installed, you should be able to start 34 | the python interpreter at the command line as: `python`. A shell will 35 | come up, and you can try out your first program: 36 | 37 | ``` 38 | print("hello, world") 39 | ``` 40 | 41 | 42 | -------------------------------------------------------------------------------- /content/01-python/misc.md: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | 3 | There are a lot of topics that we didn't cover, as well as a lot of 4 | the python standard library that we won't address. Here we introduce 5 | a few more concepts. 6 | -------------------------------------------------------------------------------- /content/01-python/myprofile.py: -------------------------------------------------------------------------------- 1 | """ 2 | A very simple profiling class. Define some timers and methods 3 | to start and stop them. Nesting of timers is tracked so we can 4 | pretty print the profiling information. 5 | 6 | # define a timer object, labeled 'my timer' 7 | a = timer('my timer') 8 | 9 | This will add 'my timer' to the list of keys in the 'my timer' 10 | dictionary. Subsequent calls to the timer class constructor 11 | will have no effect. 12 | 13 | # start timing the 'my timer' block of code 14 | a.begin() 15 | 16 | ... do stuff here ... 17 | 18 | # end the timing of the 'my timer' block of code 19 | a.end() 20 | 21 | for best results, the block of code timed should be large 22 | enough to offset the overhead of the timer class method 23 | calls. 24 | 25 | Multiple timers can be instantiated and nested. The stackCount 26 | global parameter keeps count of the level of nesting, and the 27 | timerNesting data structure stores the nesting level for each 28 | defined timer. 29 | 30 | timeReport() is called at the end to print out a summary of the 31 | timing. 32 | 33 | At present, no enforcement is done to ensure proper nesting. 34 | 35 | """ 36 | 37 | from __future__ import print_function 38 | 39 | import time 40 | 41 | timers = {} 42 | 43 | # keep basic count of how nested we are in the timers, so we can do some 44 | # pretty printing. 45 | stack_count = 0 46 | 47 | timer_nesting = {} 48 | timer_order = [] 49 | 50 | class Timer(object): 51 | 52 | def __init__ (self, name): 53 | global timers, stack_count, timer_nesting, timer_order 54 | 55 | self.name = name 56 | 57 | keys = timers.keys() 58 | 59 | if name not in keys: 60 | timers[name] = 0.0 61 | self.startTime = 0.0 62 | timer_order.append(name) 63 | timer_nesting[name] = stack_count 64 | 65 | 66 | def begin(self): 67 | global stack_count 68 | 69 | self.startTime = time.time() 70 | stack_count += 1 71 | 72 | 73 | def end(self): 74 | global timers, stack_count 75 | 76 | elapsedTime = time.time() - self.startTime 77 | timers[self.name] += elapsedTime 78 | 79 | stack_count -= 1 80 | 81 | 82 | def time_report(): 83 | global timers, timer_order, timer_nesting 84 | 85 | spacing = ' ' 86 | for key in timer_order: 87 | print(timer_nesting[key]*spacing + key + ': ', timers[key]) 88 | 89 | 90 | 91 | if __name__ == "__main__": 92 | a = Timer('1') 93 | a.begin() 94 | time.sleep(10.) 95 | a.end() 96 | 97 | b = Timer('2') 98 | b.begin() 99 | time.sleep(5.) 100 | 101 | c = Timer('3') 102 | c.begin() 103 | 104 | time.sleep(20.) 105 | 106 | b.end() 107 | c.end() 108 | 109 | time_report() 110 | -------------------------------------------------------------------------------- /content/01-python/paradigms.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/01-python/paradigms.png -------------------------------------------------------------------------------- /content/01-python/python.md: -------------------------------------------------------------------------------- 1 | # python 2 | 3 | These notebooks introduce the core python language 4 | -------------------------------------------------------------------------------- /content/01-python/python.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/01-python/python.png -------------------------------------------------------------------------------- /content/01-python/scipy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/01-python/scipy.png -------------------------------------------------------------------------------- /content/01-python/shopping.csv: -------------------------------------------------------------------------------- 1 | item,quantity,unit price,total 2 | apples,2,0.33,0.66 3 | bananas,5,0.1,0.5 4 | milk,1,2.5,2.5 5 | soda,3,1,3 6 | rolls,12,0.33,3.96 7 | eggs,1,2.5,2.5 8 | -------------------------------------------------------------------------------- /content/01-python/shopping_cart.py: -------------------------------------------------------------------------------- 1 | class Item(object): 2 | """ an item to buy """ 3 | 4 | def __init__(self, name, quantity=1): 5 | if name not in INVENTORY: 6 | raise ValueError 7 | self.name = name 8 | self.quantity = quantity 9 | 10 | def __repr__(self): 11 | return "Item({}, {})".format(self.name, self.quantity) 12 | 13 | def __eq__(self, other): 14 | return self.name == other.name 15 | 16 | def __add__(self, other): 17 | if isinstance(other, Item): 18 | if self == other: 19 | return(Item(self.name, self.quantity + other.quantity)) 20 | else: 21 | raise ValueError 22 | else: 23 | raise NotImplementedError 24 | 25 | 26 | 27 | class ShoppingCart(object): 28 | 29 | def __init__(self): 30 | self.items = [] 31 | 32 | def subtotal(self): 33 | """ return a subtotal of our items """ 34 | sub = 0.0 35 | for i in self.items: 36 | sub += i.quantity * INVENTORY[i.name] 37 | return sub 38 | 39 | def add(self, name, quantity): 40 | """ add an item to our cart """ 41 | item = Item(name, quantity) 42 | if item in self.items: 43 | # we already have this, so add to it 44 | self.items[self.items.index(item)] += item 45 | else: 46 | self.items.append(item) 47 | 48 | def remove(self, name): 49 | """ remove all of item name from the cart """ 50 | found = [q for q in self.items if q.name == name] 51 | if len(found) == 1: 52 | self.items.remove(found[0]) 53 | 54 | def report(self): 55 | for item in self.items: 56 | print("{:20} : {:4}".format(item.name, item.quantity)) 57 | 58 | -------------------------------------------------------------------------------- /content/01-python/test.txt: -------------------------------------------------------------------------------- 1 | Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do 2 | eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad 3 | minim veniam, quis nostrud exercitation ullamco laboris nisi ut 4 | aliquip ex ea commodo consequat. Duis aute irure dolor in 5 | reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla 6 | pariatur. Excepteur sint occaecat cupidatat non proident, sunt in 7 | culpa qui officia deserunt mollit anim id est laborum. 8 | 9 | -------------------------------------------------------------------------------- /content/01-python/tic_tac_toe.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | board = """ 4 | {s1:^3} | {s2:^3} | {s3:^3} 5 | -----+-----+----- 6 | {s4:^3} | {s5:^3} | {s6:^3} 7 | -----+-----+----- 123 8 | {s7:^3} | {s8:^3} | {s9:^3} 456 9 | 789 10 | """ 11 | 12 | 13 | def initialize_board(play): 14 | for n in range(9): 15 | play["s{}".format(n+1)] = "" 16 | 17 | def show_board(play): 18 | """ display the playing board. We take a dictionary with the current state of the board 19 | We rely on the board string to be a global variable""" 20 | print(board.format(**play)) 21 | 22 | 23 | def get_move(n, xo, play): 24 | """ ask the current player, n, to make a move -- make sure the square was not 25 | already played. xo is a string of the character (x or o) we will place in 26 | the desired square """ 27 | valid_move = False 28 | while not valid_move: 29 | idx = input("player {}, enter your move (1-9): ".format(n)) 30 | if play["s{}".format(idx)] == "": 31 | valid_move = True 32 | else: 33 | print("invalid: {}".format(play["s{}".format(idx)])) 34 | 35 | play["s{}".format(idx)] = xo 36 | 37 | 38 | def check_win(play): 39 | 40 | # winning combinations 41 | combos = [(1, 2, 3), (4, 5, 6), (7, 8, 9), 42 | (1, 4, 7), (2, 5, 8), (3, 6, 9), 43 | (1, 5, 9), (7, 5, 3)] 44 | 45 | winner = None 46 | 47 | for c in combos: 48 | # if we are empty, then pass 49 | if play["s{}".format(c[0])] == "": 50 | continue 51 | if play["s{}".format(c[0])] == play["s{}".format(c[1])] and \ 52 | play["s{}".format(c[0])] == play["s{}".format(c[2])]: 53 | winner = play["s{}".format(c[0])] 54 | break 55 | 56 | return winner 57 | 58 | def play_game(): 59 | """ play a game of tic-tac-toe """ 60 | 61 | # initialize the board 62 | play = {} 63 | initialize_board(play) 64 | 65 | symbols = ["x", "o"] 66 | 67 | for n in range(9): 68 | show_board(play) 69 | 70 | player = n % 2 71 | 72 | get_move(player, symbols[player], play) 73 | 74 | winner = check_win(play) 75 | if winner is not None: 76 | show_board(play) 77 | print("winner is {}!!!".format(winner)) 78 | sys.exit() 79 | 80 | if __name__ == "__main__": 81 | play_game() 82 | 83 | -------------------------------------------------------------------------------- /content/01-python/using.md: -------------------------------------------------------------------------------- 1 | # Using These Notes 2 | 3 | These notes are built via [Jupyter book](https://jupyterbook.org/), as 4 | a collection of [Jupyter](https://jupyter.org/) notebooks and markdown 5 | pages. 6 | 7 | The course is on Github at: 8 | https://github.com/sbu-python-class/python-science, and the course 9 | website is built automatically via a Github action each time a change 10 | is pushed. 11 | 12 | If you find any problems or have suggestions for improving the notes, 13 | feel free to create an issue or pull request at the Github repo. 14 | 15 | ## Interactive Usage 16 | 17 | For the Jupyter notebooks in this collection, there are a few ways to 18 | access them to run them on your own. 19 | 20 | * clicking on the {octicon}`download` icon in the upper right let's 21 | you download the raw notebook so you can run it on your local 22 | computer. 23 | 24 | * clicking on the {octicon}`rocket` icon in the upper right will allow 25 | you to run the notebook directly in the cloud. There are 2 different 26 | compute clouds: 27 | 28 | * [mybinder](https://mybinder.org/) : this is an open project with 29 | ties to the Jupyter project. It can take a few minutes for the 30 | page to appear if it hasn't been accessed recently, but then it 31 | will give you the standard Jupyter experience. 32 | 33 | * [Google colab](https://colab.research.google.com/) : this is 34 | Google's version of an online notebook, which runs directly in 35 | Google's cloud. This starts up almost instantly. 36 | 37 | ````{note} 38 | Some notebooks use [MyST Markdown](https://jupyterbook.org/en/stable/content/myst.html) to 39 | allow for more styling. To see these styles, you need to install `jupyterlab-myst`, which 40 | can be done via: 41 | ``` 42 | pip install jupyterlab_myst 43 | ``` 44 | 45 | ```` 46 | -------------------------------------------------------------------------------- /content/01-python/w4-python-modules.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Modules" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "Here we import our own module called `myprofile` (we have it in the same directory as this notebook)" 15 | ] 16 | }, 17 | { 18 | "cell_type": "code", 19 | "execution_count": null, 20 | "metadata": {}, 21 | "outputs": [], 22 | "source": [ 23 | "import myprofile" 24 | ] 25 | }, 26 | { 27 | "cell_type": "markdown", 28 | "metadata": {}, 29 | "source": [ 30 | "We have a docstring at the top -- the comments there are what appear when we ask for help" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": null, 36 | "metadata": {}, 37 | "outputs": [], 38 | "source": [ 39 | "help(myprofile)" 40 | ] 41 | }, 42 | { 43 | "cell_type": "markdown", 44 | "metadata": {}, 45 | "source": [ 46 | "This module simply provides a way to time routines (python and ipython have built-in methods for this too)" 47 | ] 48 | }, 49 | { 50 | "cell_type": "code", 51 | "execution_count": null, 52 | "metadata": {}, 53 | "outputs": [], 54 | "source": [ 55 | "t = myprofile.Timer(\"main loop\")\n", 56 | "t.begin()\n", 57 | "\n", 58 | "sum = 0.0\n", 59 | "for n in range(1000):\n", 60 | " sum += n**2\n", 61 | "\n", 62 | "\n", 63 | "t.end()\n", 64 | "myprofile.time_report()\n", 65 | "\n", 66 | "print(sum)" 67 | ] 68 | }, 69 | { 70 | "cell_type": "markdown", 71 | "metadata": {}, 72 | "source": [ 73 | "In the file `myprofile.py`, you will see a block of code under\n", 74 | "\n", 75 | "```\n", 76 | "if __name__ == \"__main__\":\n", 77 | "```\n", 78 | "\n", 79 | "That code is executed if the file is run directly, either from the commandline as:\n", 80 | "\n", 81 | "`python myprofile.py`\n", 82 | "\n", 83 | "for through the `%run` magic" 84 | ] 85 | }, 86 | { 87 | "cell_type": "code", 88 | "execution_count": null, 89 | "metadata": {}, 90 | "outputs": [], 91 | "source": [ 92 | "%run myprofile" 93 | ] 94 | } 95 | ], 96 | "metadata": { 97 | "kernelspec": { 98 | "display_name": "Python 3 (ipykernel)", 99 | "language": "python", 100 | "name": "python3" 101 | }, 102 | "language_info": { 103 | "codemirror_mode": { 104 | "name": "ipython", 105 | "version": 3 106 | }, 107 | "file_extension": ".py", 108 | "mimetype": "text/x-python", 109 | "name": "python", 110 | "nbconvert_exporter": "python", 111 | "pygments_lexer": "ipython3", 112 | "version": "3.10.2" 113 | } 114 | }, 115 | "nbformat": 4, 116 | "nbformat_minor": 4 117 | } 118 | -------------------------------------------------------------------------------- /content/02-numpy/numpy.md: -------------------------------------------------------------------------------- 1 | # NumPy 2 | 3 | The NumPy library provides a class for n-dimensional arrays of data. 4 | -------------------------------------------------------------------------------- /content/02-numpy/row_column_major.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/02-numpy/row_column_major.png -------------------------------------------------------------------------------- /content/02-numpy/sample.txt: -------------------------------------------------------------------------------- 1 | 0 -4.756772745910339 2 | 1 6.889533541096673 3 | 2 8.996896092374172 4 | 3 -1.7461017125141964 5 | 4 1.0304402925205614 6 | 5 4.635768431188638 7 | 6 5.177225916739488 8 | 7 15.964690203916664 9 | 8 -12.021098174294892 10 | 9 -18.10087879725122 11 | 10 -25.178886598285644 12 | 11 4.518925348029733 13 | 12 9.043916771177502 14 | 13 -0.5221535906039717 15 | 14 -3.1338886609447583 16 | 15 -6.914714941474996 17 | 16 -6.314263548047582 18 | 17 6.706901891085466 19 | 18 -25.971636440421232 20 | 19 -4.435372425747847 21 | 20 0.4889050161324564 22 | 21 -0.036004810755168606 23 | 22 -4.372545660650671 24 | 23 0.4047031759550273 25 | 24 3.090597990424291 26 | 25 19.306526596830842 27 | 26 6.48611581937894 28 | 27 -10.781128554191731 29 | 28 -12.85791882558559 30 | 29 -1.0278401126239605 31 | 30 -30.58842788782183 32 | 31 -6.517109634143572 33 | 32 -7.489210194855196 34 | 33 -11.105721713012358 35 | 34 4.120721916704712 36 | 35 -3.153239578756935 37 | 36 1.4135041696471733 38 | 37 22.583374665055885 39 | 38 -12.27556599640208 40 | 39 -4.793102896606837 41 | 40 -7.128537547009972 42 | 41 -17.279019221677267 43 | 42 19.655635821341445 44 | 43 -1.2745066768475497 45 | 44 3.738058165511088 46 | 45 10.481959096601695 47 | 46 -12.814187304346124 48 | 47 -22.424530149878166 49 | 48 4.137834007998959 50 | 49 -0.04131996932026964 51 | 50 7.375298054261892 52 | 51 -4.098385522108854 53 | 52 -5.599571617055626 54 | 53 -13.253443154026934 55 | 54 16.290743431455287 56 | 55 10.424184766192798 57 | 56 -4.27251751782754 58 | 57 19.01684691299122 59 | 58 3.15448738602801 60 | 59 -9.704807918052413 61 | 60 -0.0008101176931862717 62 | 61 6.104424953162043 63 | 62 24.47811290783359 64 | 63 14.846618329919092 65 | 64 -2.186378655814549 66 | 65 9.86177633783792 67 | 66 12.724976950604734 68 | 67 4.037245731028271 69 | 68 -0.656843975486256 70 | 69 15.37262575716834 71 | 70 -7.880872346846276 72 | 71 2.54070374695715 73 | 72 -1.022544832116583 74 | 73 20.91034858050119 75 | 74 9.222541985448974 76 | 75 -11.056628565277206 77 | 76 27.93950830400997 78 | 77 -6.032857683782997 79 | 78 18.098345716611153 80 | 79 38.59487842850004 81 | 80 -0.8720942826849941 82 | 81 1.7229720788142675 83 | 82 -4.174088180887814 84 | 83 -8.318962830280652 85 | 84 14.512558782294388 86 | 85 5.630837289759344 87 | 86 13.097667005419458 88 | 87 9.517210836578036 89 | 88 -3.2730322970019206 90 | 89 14.22975371499751 91 | 90 -12.903078745763068 92 | 91 10.69546941555894 93 | 92 -6.12535752853502 94 | 93 -0.0538615350527278 95 | 94 8.344238543768178 96 | 95 12.569544805707704 97 | 96 -1.5730683048208713 98 | 97 9.588349649640545 99 | 98 -17.791062662128468 100 | 99 -4.613995471504272 101 | -------------------------------------------------------------------------------- /content/02-numpy/slicing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/02-numpy/slicing.png -------------------------------------------------------------------------------- /content/03-practices/git.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/03-practices/git.png -------------------------------------------------------------------------------- /content/04-matplotlib/NOTES: -------------------------------------------------------------------------------- 1 | anatomy of a figure: 2 | 3 | http://matplotlib.org/faq/usage_faq.html#parts-of-a-figure 4 | 5 | 6 | tutorial notebook exists -------------------------------------------------------------------------------- /content/04-matplotlib/anatomy1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/04-matplotlib/anatomy1.png -------------------------------------------------------------------------------- /content/04-matplotlib/matplotlib.md: -------------------------------------------------------------------------------- 1 | # matplotlib 2 | 3 | matplotlib is the core plotting library for python. 4 | -------------------------------------------------------------------------------- /content/04-matplotlib/matplotlib.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/04-matplotlib/matplotlib.pdf -------------------------------------------------------------------------------- /content/04-matplotlib/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/04-matplotlib/test.png -------------------------------------------------------------------------------- /content/05-scipy/bisection.avi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/05-scipy/bisection.avi -------------------------------------------------------------------------------- /content/05-scipy/condition-example.py: -------------------------------------------------------------------------------- 1 | def hilbert(n): 2 | """ return a Hilbert matrix, H_ij = (i + j - 1)^{-1} """ 3 | 4 | H = np.zeros((n,n), dtype=np.float64) 5 | 6 | for i in range(1, n+1): 7 | for j in range(1, n+1): 8 | H[i-1,j-1] = 1.0/(i + j - 1.0) 9 | return H 10 | 11 | import scipy.linalg as linalg 12 | import numpy as np 13 | 14 | n = 13 15 | H = hilbert(n) 16 | x = np.arange(n) 17 | print(x) 18 | b = np.dot(H,x) 19 | print(b) 20 | 21 | xnew = linalg.solve(H, b) 22 | print(xnew) 23 | print(np.linalg.cond(H)) 24 | 25 | xs = linalg.lstsq(H, b) 26 | print(xs) 27 | -------------------------------------------------------------------------------- /content/05-scipy/newton.avi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/05-scipy/newton.avi -------------------------------------------------------------------------------- /content/05-scipy/orbit_setup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/05-scipy/orbit_setup.png -------------------------------------------------------------------------------- /content/05-scipy/pendulum_answer.py: -------------------------------------------------------------------------------- 1 | from scipy.integrate import ode 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | 5 | def rhs(t, Y, q, omega_d, b): 6 | """ damped driven pendulum system derivatives. Here, Y = (theta, omega) are 7 | the solution variables. """ 8 | f = np.zeros_like(Y) 9 | 10 | f[0] = Y[1] 11 | f[1] = -q*Y[1] - np.sin(Y[0]) + b*np.cos(omega_d*t) 12 | 13 | return f 14 | 15 | def restrict_theta(theta): 16 | """ convert theta to be restricted to lie between -pi and pi""" 17 | tnew = theta + np.pi 18 | tnew += -2.0*np.pi*np.floor(tnew/(2.0*np.pi)) 19 | tnew -= np.pi 20 | return tnew 21 | 22 | 23 | def int_pendulum(theta0, q, omega_d, b, tend): 24 | r = ode(rhs) 25 | r.set_integrator("dopri5", nsteps=150000) 26 | 27 | sol = [] 28 | r.set_solout(lambda t, y: sol.append([t, *y])) 29 | 30 | t0 = 0.0 31 | omega0 = 0.0 32 | r.set_initial_value((theta0, omega0), t0) 33 | 34 | r.set_f_params(q, omega_d, b) 35 | 36 | r.integrate(tend) 37 | return np.array(sol) 38 | 39 | 40 | s = int_pendulum(np.radians(60), 0.5, 0.6666, 1.5, 200.0) 41 | q = int_pendulum(np.radians(60.001), 0.5, 0.6666, 1.5, 200.0) 42 | 43 | plt.plot(s[:,0], restrict_theta(s[:,1])) 44 | plt.plot(q[:,0], restrict_theta(q[:,1])) 45 | 46 | plt.show() 47 | -------------------------------------------------------------------------------- /content/05-scipy/pendulum_fft.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from scipy.integrate import ode 3 | import matplotlib.pyplot as plt 4 | 5 | 6 | def rhs(t, Y, q, omega_d, b): 7 | """ damped driven pendulum system derivatives. Here, Y = (theta, omega) are 8 | the solution variables. """ 9 | f = np.zeros_like(Y) 10 | 11 | f[0] = Y[1] 12 | f[1] = -q*Y[1] - np.sin(Y[0]) + b*np.cos(omega_d*t) 13 | 14 | return f 15 | 16 | def restrict_theta(theta): 17 | """ convert theta to be restricted to lie between -pi and pi""" 18 | tnew = theta + np.pi 19 | tnew += -2.0*np.pi*np.floor(tnew/(2.0*np.pi)) 20 | tnew -= np.pi 21 | return tnew 22 | 23 | def int_pendulum(theta0, q, omega_d, b, tend, dt): 24 | """ integrate the pendulum with a fixed timestep, dt""" 25 | r = ode(rhs) 26 | r.set_integrator("dopri5", nsteps=150000, first_step=dt, max_step=dt, dfactor=1.0) 27 | 28 | sol = [] 29 | r.set_solout(lambda t, y: sol.append([t, *y])) 30 | 31 | t0 = 0.0 32 | omega0 = 0.0 33 | r.set_initial_value((theta0, omega0), t0) 34 | 35 | r.set_f_params(q, omega_d, b) 36 | 37 | r.integrate(tend) 38 | return np.array(sol) 39 | 40 | def power_spectrum(t, theta0): 41 | """ return the power spectrum of theta. For the frequency 42 | component, return it in terms of omega """ 43 | 44 | theta = restrict_theta(theta0) 45 | 46 | # fill in the rest -- take the FFT of theta and return omega_k and 47 | # the transform of theta 48 | N = len(t) 49 | F = (2.0/N)*np.fft.rfft(theta) 50 | 51 | k = np.fft.rfftfreq(N) 52 | kfreq = 2.0*np.pi*k*N/max(t) 53 | 54 | return kfreq, F 55 | 56 | 57 | # normal (undamped, not driven pendulum) 58 | s = int_pendulum(np.radians(10), 0.0, 0.6666, 0.0, 200.0, 0.1) 59 | 60 | omega, F = power_spectrum(s[:,0], s[:,1]) 61 | 62 | plt.plot(omega, np.abs(F)**2) 63 | plt.xlim(0.0, 2.0) 64 | plt.show() 65 | 66 | # chaotic pendulum 67 | s = int_pendulum(np.radians(10), 0.5, 0.6666, 1.15, 200.0, 0.1) 68 | 69 | omega, F = power_spectrum(s[:,0], s[:,1]) 70 | 71 | plt.plot(omega, np.abs(F)**2) 72 | plt.xlim(0.0, 2.0) 73 | plt.show() 74 | -------------------------------------------------------------------------------- /content/05-scipy/rectangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/05-scipy/rectangle.png -------------------------------------------------------------------------------- /content/05-scipy/rk4_Euler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/05-scipy/rk4_Euler.png -------------------------------------------------------------------------------- /content/05-scipy/rk4_final.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/05-scipy/rk4_final.png -------------------------------------------------------------------------------- /content/05-scipy/rk4_initial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/05-scipy/rk4_initial.png -------------------------------------------------------------------------------- /content/05-scipy/rk4_k1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/05-scipy/rk4_k1.png -------------------------------------------------------------------------------- /content/05-scipy/rk4_k2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/05-scipy/rk4_k2.png -------------------------------------------------------------------------------- /content/05-scipy/rk4_k3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/05-scipy/rk4_k3.png -------------------------------------------------------------------------------- /content/05-scipy/rk4_k4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/05-scipy/rk4_k4.png -------------------------------------------------------------------------------- /content/05-scipy/scipy.md: -------------------------------------------------------------------------------- 1 | # SciPy 2 | 3 | SciPy provides implementations of many common numerical methods. 4 | -------------------------------------------------------------------------------- /content/05-scipy/scipy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/05-scipy/scipy.png -------------------------------------------------------------------------------- /content/05-scipy/simpsons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/05-scipy/simpsons.png -------------------------------------------------------------------------------- /content/05-scipy/trapezoid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/05-scipy/trapezoid.png -------------------------------------------------------------------------------- /content/06-sympy/sympy.md: -------------------------------------------------------------------------------- 1 | # SymPy 2 | 3 | SymPy is the symbolic math library for python. A key design feature 4 | of it is that it can interoperate with all of the libraries we've 5 | already seen. 6 | -------------------------------------------------------------------------------- /content/07-pandas/exercises.txt: -------------------------------------------------------------------------------- 1 | -- work with the World Bank data 2 | -- curve fit from pandas 3 | -------------------------------------------------------------------------------- /content/07-pandas/ideas.txt: -------------------------------------------------------------------------------- 1 | https://gist.github.com/jakevdp/9ffd72a81c1af80a10314cba0569af84 2 | -------------------------------------------------------------------------------- /content/07-pandas/pandas_solutions.txt: -------------------------------------------------------------------------------- 1 | Q1: 2 | 3 | np.allclose(names.groupby(["year", "sex"]).prop.sum(), 1.0) 4 | 5 | 6 | Q2: 7 | 8 | boys = top[top.sex == "M"] 9 | girls = top[top.sex == "F"] 10 | 11 | Q3: 12 | 13 | all_names = top["name"].unique() 14 | all_names.dtype 15 | 16 | len(all_names) 17 | 18 | 19 | Q4: 20 | 21 | what are all the names that appear for both boys and girls? 22 | 23 | boy_names = top[top["sex"] == "M"]["name"].unique() 24 | girl_names = top[top["sex"] == "F"]["name"].unique() 25 | joint = np.intersect1d(boy_names, girl_names) 26 | 27 | 28 | Q5: 29 | 30 | def get_count(group, q=0.5): 31 | group = group.sort_values(by="prop", ascending=False) 32 | return group["prop"].cumsum().searchsorted(0.5)[0] + 1 33 | 34 | diversity = top.groupby(["year", "sex"]).apply(get_count) 35 | diversity = diversity.unstack("sex") 36 | diversity.plot() 37 | 38 | -------------------------------------------------------------------------------- /content/07-pandas/sample.csv: -------------------------------------------------------------------------------- 1 | "student", "hw 1", "hw 2", "hw 3", "hw 4", "exam" 2 | "A", 10 , 9 , 10 , 7 , 97 3 | "B", 8 , 7 , 9 , 9 , 82 4 | "C", , 9 , 6 , 5 , 75 5 | "D", 8 , 9 , 9 , 9 , 90 6 | "E", , 10 , 10 , 10 , 95 7 | "F", 8 , 2 , 6 , 7 , 66 8 | "G", 6 , , 4 , 5 , 60 9 | "H", 8 , 8 , 9 , 8 , 84 10 | "I", 10 , 7 , 10 , 10 , 92 11 | "J", 10 , 6 , 9 , 9 , 91 12 | "K", 8 , 7 , 6 , 8 , 87 13 | "L", 3 , 8 , 5 , 7 , 71 14 | "M", 9 , 9 , 8 , 9 , 94 15 | "N", 8 , 10 , 9 , 9 , 90 16 | "O", 10 , 10 , 10 , 9 , 99 17 | "P", 8 , 9 , 8 , 10 , 94 18 | "Q", 5 , 7 , 6 , 5 , 78 19 | 20 | 21 | -------------------------------------------------------------------------------- /content/09-packages/NOTES: -------------------------------------------------------------------------------- 1 | Excellent discussuion about the various packages: 2 | 3 | http://stackoverflow.com/questions/6344076/differences-between-distribute-distutils-setuptools-and-distutils2 4 | 5 | 6 | pip and setuptools 7 | 8 | http://python-packaging-user-guide.readthedocs.org/en/latest/tutorial.html -------------------------------------------------------------------------------- /content/09-packages/argparse_example.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # to get usage: use -h 4 | import argparse 5 | 6 | 7 | def setup_args(): 8 | 9 | # simple example of argparse 10 | 11 | parser = argparse.ArgumentParser() 12 | parser.add_argument("-a", help="the -a option", action="store_true") 13 | parser.add_argument("-b", help="-b takes a number", type=int, default=0) 14 | parser.add_argument("-c", help="-c takes a string", type=str, default=None) 15 | parser.add_argument("--darg", help="the --darg option", action="store_true") 16 | parser.add_argument("--earg", help="--earg takes a string", type=str, metavar="test", 17 | default="example string") 18 | 19 | # extra arguments (positional) 20 | parser.add_argument("extras", metavar="extra", type=str, nargs="*", 21 | help="optional positional arguments") 22 | 23 | return parser.parse_args() 24 | 25 | 26 | if __name__ == "__main__": 27 | 28 | args = setup_args() 29 | 30 | 31 | if args.a: 32 | print("-a set") 33 | print(f"-b = {args.b}") 34 | print(f"-c = {args.c}") 35 | if args.darg: 36 | print("--dargs set") 37 | print(f"--earg value = {args.earg}") 38 | 39 | print(" ") 40 | print("extra positional arguments: ") 41 | if len(args.extras) > 0: 42 | for e in args.extras: 43 | print(e) 44 | -------------------------------------------------------------------------------- /content/09-packages/packaging.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/09-packages/packaging.pdf -------------------------------------------------------------------------------- /content/09-packages/python-arguments.md: -------------------------------------------------------------------------------- 1 | # Command line arguments 2 | 3 | For standalone programs, we often want to have our program take 4 | command line arguments that affect the runtime behavior of our 5 | program. There are a variety of mechanisms to do this in python, but 6 | the best option is the [argparse 7 | module](https://docs.python.org/3/library/argparse.html). 8 | 9 | Here's an example of using `argparse` to take a variety of options: 10 | 11 | ```{literalinclude} argparse_example.py 12 | --- 13 | language: python 14 | ``` 15 | 16 | A nice feature of `argparse` is that it automatically generates help for us. If 17 | we place the above code in `argparse_example.py` then we can do: 18 | 19 | ```python 20 | python argparse_example.py --help 21 | ``` 22 | -------------------------------------------------------------------------------- /content/09-packages/python-modules.md: -------------------------------------------------------------------------------- 1 | # Python Modules 2 | 3 | So far, we've been writing our code all in Jupyter. But when it comes 4 | time to write code that we want to reuse, we want to put it into a 5 | standalone `*.py` file. 6 | 7 | Then we can load it on in python (or Jupyter) and use the capabilities 8 | it provides or make it a standalone program that can be run from the 9 | command line. 10 | 11 | ```{tip} 12 | Jupyter is great for interactive explorations and sharing your workflow with others 13 | in a self-contained way. But if there is an operation that you do over and over, 14 | you should put it into a separate module that you import. That way you only need to 15 | maintain and debug a single instance of the function, and all your workflows can reuse it. 16 | ``` 17 | 18 | 19 | ## Editors 20 | 21 | There are a number of popular editors for writing python source. Some 22 | popular ones include: 23 | 24 | * spyder: https://www.spyder-ide.org/ 25 | 26 | * VS Code: https://code.visualstudio.com/ 27 | 28 | * emacs / vi 29 | 30 | 31 | ## Standalone module 32 | 33 | Here's a very simply module (lets call it `hello.py`): 34 | 35 | ```python 36 | def hello(): 37 | print("hello") 38 | 39 | if __name__ == "__main__": 40 | hello() 41 | ``` 42 | 43 | There are two ways we can use this. 44 | 45 | * Inside of python (or IPython), we can do: 46 | 47 | ```python 48 | import hello 49 | hello.hello() 50 | ``` 51 | 52 | * From the command line, we can do: 53 | 54 | ```python 55 | python hello.py 56 | ``` 57 | 58 | Additionally, on a Unix system, we can add: 59 | 60 | ```python 61 | #!/usr/bin/env python3 62 | ``` 63 | 64 | to the top and then mark the file as executable, via: 65 | 66 | ```bash 67 | chmod a+x hello.py 68 | ``` 69 | 70 | allowing us to execute it simply as: 71 | 72 | ```bash 73 | ./hello.py 74 | ``` 75 | 76 | ```{hint} 77 | Here we see how the `__name__` variable is treated by python: 78 | 79 | * If we import our module into python, then `__name__` is set to the module name 80 | 81 | * If we run the module from the command line, then `__name__` is set to `__main__` 82 | ``` 83 | 84 | ## Changing module contents 85 | 86 | If we make changes to our module file, then we need to re-import it. This can be done as: 87 | 88 | ```python 89 | import importlib 90 | example = importlib.reload(example) 91 | ``` 92 | -------------------------------------------------------------------------------- /content/09-packages/python-more-modules.md: -------------------------------------------------------------------------------- 1 | # Module Paths 2 | 3 | How does python find modules? It has a [search order](https://docs.python.org/3/tutorial/modules.html#the-module-search-path): 4 | 5 | * current directory 6 | 7 | * `PYTHONPATH` environment variable (this follows the same format as 8 | the shell `PATH` environment variable) 9 | 10 | * System-wide python installation default path (usually has a 11 | `site-packages` directory) 12 | 13 | We can look at the path via ``sys.path``. On my machine I get: 14 | 15 | ``` 16 | ['/home/zingale/.local/bin', 17 | '/home/zingale/classes/python-science/content/09-packages', 18 | '/home/zingale/classes/numerical_exercises', 19 | '/home/zingale/classes/astro_animations', 20 | '/usr/lib64/python312.zip', 21 | '/usr/lib64/python3.12', 22 | '/usr/lib64/python3.12/lib-dynload', 23 | '', 24 | '/home/zingale/.local/lib/python3.12/site-packages', 25 | '/usr/lib64/python3.12/site-packages', 26 | '/usr/lib/python3.12/site-packages'] 27 | 28 | ``` 29 | 30 | ```{note} 31 | You can explicitly add paths to the ``sys.path`` by setting the `PYTHONPATH` 32 | environment variable. 33 | ``` 34 | 35 | 36 | Notice that the general places that it looks are in `~/.local` and in 37 | `/usr`. The first is the user-specific path—you can install things 38 | here without admin privileges. The second is a system-wide path. 39 | 40 | You can find your user-specific path via: 41 | 42 | ```bash 43 | python3 -m site --user-site 44 | ``` 45 | 46 | on my machine, this gives: 47 | 48 | ``` 49 | /home/zingale/.local/lib/python3.12/site-packages 50 | ``` 51 | 52 | ```{tip} 53 | Using `PYTHONPATH` to quickly add a module to your search path is an easy hack, 54 | but if you are developing a library that will be used by others, it is better 55 | to make the modules installable to the system search paths. This is where 56 | _packaging_ comes into play. 57 | ``` 58 | -------------------------------------------------------------------------------- /content/09-packages/python-tools.md: -------------------------------------------------------------------------------- 1 | # Tools to Make Your Life Easier 2 | 3 | ## Version control 4 | 5 | Generally, you should put your project into version control. The most widely used 6 | package today is [git](https://git-scm.com/book/en/v2/Getting-Started-About-Version-Control). 7 | git will track the changes you make to your code, allow you to revert changes, collaboratively 8 | develop with others, work on several different features independently from one another while 9 | keeping the main codebase clean and more. 10 | 11 | git is often used together with [github](https://github.com), which provides a web-based view 12 | of your source code and provides additional mechanisms for collaboration. 13 | 14 | A nice introduction to git/github is provided by the [Software 15 | Carpentry _Version Control with Git_ 16 | lesson](https://swcarpentry.github.io/git-novice/). 17 | 18 | 19 | ## Code checkers 20 | 21 | There are a number of tools that help check code for formatting and 22 | syntax errors that are quite useful for developers. Many projects 23 | automatically enforce these tools on changes submitted to github. 24 | 25 | ```{tip} 26 | Many editors have plugins that can automatically run these tools 27 | as your write your code. 28 | ``` 29 | 30 | * [flake8](https://flake8.pycqa.org/en/latest/) 31 | 32 | `flake8` is a checker for [PEP 8](https://peps.python.org/pep-0008/) 33 | style conformance. You can turn off checks that you don't like 34 | via a [`.flake8` 35 | file](https://flake8.pycqa.org/en/latest/user/configuration.html#configuration-locations). 36 | 37 | * [pylint](https://pypi.org/project/pylint/) 38 | 39 | `pylint` is a static code analyzer. It can find errors and also suggest improvements 40 | to your code. You can [generate a configuration file](https://pylint.readthedocs.io/en/latest/user_guide/configuration/index.html) 41 | to customize its behavior (or add a section to `pyproject.toml`). 42 | 43 | * [black](https://pypi.org/project/black/) 44 | 45 | `black` is an _uncompromising code formatted_. It will automatically rewrite your code 46 | based on PEP-8 style. 47 | 48 | * [pyupgrade](https://github.com/asottile/pyupgrade) 49 | 50 | `pyupgrade` will upgrade source to a later python standard, making 51 | use of new features where available. For instance, you can run as: 52 | 53 | ``` 54 | pyupgrade --py39-plus file.py 55 | ``` 56 | 57 | to update to python 3.9 support. 58 | 59 | * [isort](https://pycqa.github.io/isort/) 60 | 61 | `isort` simply sorts the module imports at the top of your modules, 62 | grouping the standard python ones together followed by 63 | package-specific ones. 64 | -------------------------------------------------------------------------------- /content/09-packages/python_environment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/09-packages/python_environment.png -------------------------------------------------------------------------------- /content/09-packages/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/09-packages/test.png -------------------------------------------------------------------------------- /content/10-testing/notes.txt: -------------------------------------------------------------------------------- 1 | -- define testing: unit, integration, regression testing 2 | 3 | (also verification and validation) 4 | 5 | -- nose and unit tests 6 | 7 | very nice: 8 | http://ivory.idyll.org/articles/nose-intro.html 9 | 10 | 11 | http://pythontesting.net/framework/nose/nose-introduction/ 12 | 13 | -- regression tests 14 | 15 | * write a comparison tool 16 | * self-documenting file helps 17 | 18 | -- reproducibility 19 | 20 | -- coverage 21 | 22 | http://blog.jameskyle.org/2010/10/nose-unit-testing-quick-start/ 23 | 24 | nosetests-3 -sv --with-coverage --cover-erase --cover-inclusive --cover-package=. 25 | -------------------------------------------------------------------------------- /content/10-testing/pytest: -------------------------------------------------------------------------------- 1 | pip3 install -U pytest --user 2 | 3 | note: it might install it in ~/.local/bin/ but you might have a 4 | different version of pytest elsewhere in your path. 5 | 6 | the older version was `py.test` now, it is `pytest` 7 | 8 | to make sure that you get the version consistent with your install, you can do: 9 | 10 | python3 -m pytest 11 | 12 | -------------------------------------------------------------------------------- /content/10-testing/real-world-example.md: -------------------------------------------------------------------------------- 1 | # Real World Example 2 | 3 | Let's look at the testing in a larger python package. We'll use our 4 | group's python hydrodynamics code, pyro, as a test: 5 | 6 | https://github.com/python-hydro/pyro2 7 | 8 | ## Installing 9 | 10 | We need to install the package first, via the `setup.py`: 11 | 12 | ```bash 13 | python setup.py install --user 14 | ``` 15 | 16 | or alternately as 17 | 18 | ```bash 19 | pip install . 20 | ``` 21 | 22 | ## Running the tests 23 | 24 | We can run the tests via: 25 | 26 | ```bash 27 | pytest -v pyro 28 | ``` 29 | 30 | ## Using notebooks as tests 31 | 32 | Sometimes we want to use Jupyter notebooks as tests themselves—this 33 | is enabled via the [nbval plugin](https://nbval.readthedocs.io/en/latest/). In 34 | this way, pytest will execute the cells in the notebook and compare 35 | the result to the result stored in the notebook. If they agree, then 36 | the test passes. 37 | 38 | Sometimes there's a particular cell that we don't want to be part of the 39 | testing—we can disable these on a cell-by-cell basis by [adding 40 | tags to a cell](https://nbval.readthedocs.io/en/latest/#Using-tags-instead-of-comments). 41 | 42 | We can test notebooks as: 43 | 44 | ```bash 45 | pytest -v --nbval pyro 46 | ``` 47 | 48 | ## Coverage report 49 | 50 | The [pytest-cov](https://pytest-cov.readthedocs.io/en/latest/) plugin enables the generation 51 | of a coverage report. This will tell you what fraction of each python file was tested. 52 | We run this as: 53 | 54 | ```bash 55 | pytest -v --cov=pyro --nbval pyro 56 | ``` 57 | 58 | We can also generate a more detailed interactive report with 59 | 60 | ```bash 61 | coverage html 62 | ``` 63 | 64 | ## Other types of tests 65 | 66 | Unit tests are only one form of testing—they test a function in 67 | isolation of others. Sometimes we need to test everything working together. 68 | For scientific codes, regression testing is often used. The basic workflow 69 | is: 70 | 71 | * Start with the project working in a way you are happy with 72 | 73 | * Store the output of one (or more) runs as a _benchmark_. 74 | 75 | * Each time you make changes, run the code and compare the new output 76 | to the stored benchmark. 77 | 78 | * If there are no differences, then your changes are likely good 79 | (but there is always the case of some feature not being tested). 80 | 81 | * If there are differences, then either you introduced a bug, in which 82 | case you should fix it, or you fixed a bug, in which case you should 83 | update the benchmarks. 84 | 85 | For our example code, pyro, the regression test runs simulations using 86 | all the different solvers and compares against the stored output, zone-by-zone 87 | for any differences. The comparison itself is built into the main driver 88 | of the code and can be invoked as: 89 | 90 | ```bash 91 | ./pyro/test.py 92 | ``` 93 | -------------------------------------------------------------------------------- /content/10-testing/testing.md: -------------------------------------------------------------------------------- 1 | # Testing 2 | 3 | Testing is an integral part of the software development process. We want to catch 4 | mistakes early, before they go on to affect our results. 5 | 6 | ## Types of testing 7 | 8 | There are a lot of different types of software testing that exist. 9 | Most commonly, for scientific codes, we hear about: 10 | 11 | * Unit testing : Tests that a single function does what it was designed to do 12 | 13 | * Integration testing : Tests whether the individual pieces work together as intended. 14 | Sometimes done one piece at a time (iteratively) 15 | 16 | * Regression testing : Checks whether code changes have changed answers 17 | 18 | * Verification & Validation (from the science perspective) 19 | 20 | * Verification: are we solving the equations correctly? 21 | 22 | * Validation: are we solving the correct equations? 23 | 24 | ## Automating testing 25 | 26 | The best testing is automated. Github provides a *continuous integration* service that can 27 | be run on pull requests. You write a short definition (a Github workflow) that tells Github 28 | how to run your tests and then any time there is a change, the tests are run. 29 | 30 | ## Unit testing 31 | 32 | * When to write tests? 33 | 34 | * Some people advocate writing a unit test for a specification 35 | before you write the functions they will test 36 | 37 | * This is called Test-driven development (TDD): 38 | https://en.wikipedia.org/wiki/Test-driven_development 39 | 40 | * This helps you understand the interface, return values, 41 | side-effects, etc. of what you intend to write 42 | 43 | * Often we already have code, so we can start by writing tests to 44 | cover some core functionality 45 | 46 | * Add new tests when you encounter a bug, precisely to ensure that 47 | this bug doesn’t arise again 48 | 49 | * Tests should be short and simple 50 | 51 | * You want to be able to run them frequently 52 | 53 | * The more granular your tests are, the easier it will be to track down bugs 54 | 55 | 56 | -------------------------------------------------------------------------------- /content/10-testing/unit_integration.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/10-testing/unit_integration.gif -------------------------------------------------------------------------------- /content/11-machine-learning/README: -------------------------------------------------------------------------------- 1 | Note: on older machines, tensorflow generates an illegal instruction 2 | and crashes python on import. The issue is the CPU instructions it 3 | was compiled with. The solution seems to be to drop down to 4 | tensorflow 1.5: 5 | 6 | https://github.com/tensorflow/tensorflow/issues/17411 7 | 8 | On my system, I need to make sure I got numpy from pip (instead of the 9 | Fedora package manager). 10 | 11 | 12 | 13 | clustering examples: 14 | 15 | https://laxmikants.github.io/blog/neural-network-using-make-moons-dataset/ 16 | -------------------------------------------------------------------------------- /content/11-machine-learning/ideas.txt: -------------------------------------------------------------------------------- 1 | Packages to try: 2 | 3 | -- keras 4 | -- tensorflow 5 | -- scikit-learn 6 | 7 | Some nice tutorials: 8 | 9 | -- https://github.com/zotroneneis/machine_learning_basics 10 | 11 | 12 | https://elitedatascience.com/keras-tutorial-deep-learning-in-python 13 | 14 | 15 | types of machine learning: 16 | 17 | https://towardsdatascience.com/the-mostly-complete-chart-of-neural-networks-explained-3fb6f2367464 18 | 19 | -------------------------------------------------------------------------------- /content/11-machine-learning/machine-learning.md: -------------------------------------------------------------------------------- 1 | # Machine Learning 2 | 3 | We'll look at a popular library for machine learning. 4 | -------------------------------------------------------------------------------- /content/11-machine-learning/model.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/11-machine-learning/model.png -------------------------------------------------------------------------------- /content/11-machine-learning/nn_fig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/11-machine-learning/nn_fig.png -------------------------------------------------------------------------------- /content/11-machine-learning/nn_fig2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/11-machine-learning/nn_fig2.png -------------------------------------------------------------------------------- /content/11-machine-learning/nn_fig_hidden.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/11-machine-learning/nn_fig_hidden.png -------------------------------------------------------------------------------- /content/11-machine-learning/sigmoid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/11-machine-learning/sigmoid.png -------------------------------------------------------------------------------- /content/11-machine-learning/sigmoid.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | import numpy as np 3 | 4 | 5 | def sigmoid(p): 6 | return 1 / (1 + np.exp(-p)) 7 | 8 | p = np.linspace(-10, 10, 200) 9 | 10 | fig, ax = plt.subplots() 11 | 12 | ax.plot(p, sigmoid(p)) 13 | 14 | fig.savefig("sigmoid.png") 15 | -------------------------------------------------------------------------------- /content/12-extensions/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/12-extensions/test.png -------------------------------------------------------------------------------- /content/CHANGES: -------------------------------------------------------------------------------- 1 | -- make this S/U grading 2 | 3 | -- perhaps have BB "grade" participation on the forum? 4 | 5 | 6 | debugging: 7 | 8 | memray: https://github.com/bloomberg/memray 9 | -------------------------------------------------------------------------------- /content/Introduction.md: -------------------------------------------------------------------------------- 1 | # PHY 546: Python for Scientific Computing 2 | 3 | ![xkcd](01-python/python.png) 4 | 5 | (from https://xkcd.com) 6 | 7 | ## Why python? 8 | 9 | * Python is a very high-level language 10 | 11 | * it provides many complex data-structures (lists, dictionaries, ...) 12 | 13 | * your code is shorter than a comparable algorithm in a compiled language 14 | 15 | * Many powerful libraries to perform complex tasks 16 | 17 | * Parse structured inputs files 18 | 19 | * send e-mail 20 | 21 | * interact with the operating system 22 | 23 | * make plots 24 | 25 | * make GUIs 26 | 27 | * do scientific computations 28 | 29 | * ... 30 | 31 | * Python makes it easy to prototype new tools 32 | 33 | * Python is cross-platform and Free 34 | 35 | ## Language Features 36 | 37 | Some of the language features are: 38 | 39 | * Dynamical typing 40 | 41 | * Object-oriented foundation 42 | 43 | * Extensible (easy to call Fortran, C/C++, ...) 44 | 45 | * Automatic memory management (garbage collection) 46 | 47 | * Ease of readability (whitespace matters) 48 | 49 | 50 | ## Scientific python 51 | 52 | Perhaps most importantly, and why we are here: 53 | 54 | > Python has been widely adopted in the scientific community. 55 | 56 | -------------------------------------------------------------------------------- /content/NOTES: -------------------------------------------------------------------------------- 1 | hdf5: http://blog.tremily.us/posts/HDF5/ 2 | this shows with h5py 3 | 4 | 5 | --- 6 | 7 | show python coding style in applications section 8 | 9 | 10 | ---- 11 | 12 | pip vs setup.py 13 | 14 | http://stackoverflow.com/questions/15724093/difference-between-python-setup-py-install-and-pip-install 15 | -------------------------------------------------------------------------------- /content/_config.yml: -------------------------------------------------------------------------------- 1 | # Book settings 2 | # Learn more at https://jupyterbook.org/customize/config.html 3 | 4 | title: "PHY 546: Python for Scientific Computing" 5 | author: Michael Zingale 6 | #logo: logo.png 7 | copyright: "2022" 8 | 9 | # Force re-execution of notebooks on each build. 10 | # See https://jupyterbook.org/content/execute.html 11 | execute: 12 | execute_notebooks: force 13 | allow_errors: true 14 | 15 | # Define the name of the latex output file for PDF builds 16 | latex: 17 | latex_documents: 18 | targetname: book.tex 19 | 20 | # Information about where the book exists on the web 21 | repository: 22 | url: https://github.com/sbu-python-class/python-science 23 | path_to_book: content # Optional path to your book, relative to the repository root 24 | branch: main # Which branch of the repository should be used when creating links (optional) 25 | 26 | # Add GitHub buttons to your book 27 | # See https://jupyterbook.org/customize/config.html#add-a-link-to-your-repository 28 | html: 29 | use_issues_button: true 30 | use_repository_button: true 31 | extra_footer: | 32 |

33 | © 2023-2025; CC-BY-NC-SA 4.0 34 |

35 | 36 | sphinx: 37 | config: 38 | html_show_copyright: false 39 | nbsphinx_timeout: 300 40 | nb_execution_timeout: 300 41 | 42 | launch_buttons: 43 | binderhub_url: "https://mybinder.org" 44 | colab_url: "https://colab.research.google.com" 45 | 46 | parse: 47 | extensions: 48 | - myst_parser 49 | - sphinx_design 50 | 51 | myst_enable_extensions: 52 | # don't forget to list any other extensions you want enabled, 53 | # including those that are enabled by default! 54 | - amsmath 55 | - dollarmath 56 | - linkify 57 | - colon_fence 58 | -------------------------------------------------------------------------------- /content/_static/myfile.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,100;0,300;0,400;0,700;0,900;1,100;1,300;1,400;1,700;1,900&display=swap'); 2 | @import url('https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400;1,500;1,600;1,700&display=swap'); 3 | 4 | body { 5 | font-family: "Open Sans", sans-serif; 6 | } 7 | 8 | .heading-style, h1, h2, h3, h4, h5, h6 { 9 | font-family: "Open Sans", sans-serif; 10 | } 11 | -------------------------------------------------------------------------------- /content/git/distributed_version_control.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/git/distributed_version_control.png -------------------------------------------------------------------------------- /content/git/git-remotes.md: -------------------------------------------------------------------------------- 1 | # Git Remotes 2 | 3 | ## Bare Repository 4 | 5 | So far, we've just been using our git repo for ourselves. 6 | 7 | Let's look back at the figure illustrating ways we can share with distributed version control: 8 | 9 | ```{image} distributed_version_control.png 10 | :align: center 11 | ``` 12 | 13 | When multiple developers are working on the same code together, it is 14 | convenient to have a central repository that everyone can communicate 15 | with. 16 | 17 | We use a special `bare` repository for this purpose. A bare repo 18 | has all of the metadata for the project, but we don't work directly in 19 | it. This way we avoid the risk of having unsaved changed in the repo 20 | that other people are using to synchronize with. 21 | 22 | Let's create a bare repo from our `project2` project. From your home directory 23 | (assuming that project2 is `~/project2/`, we do: 24 | 25 | ```bash 26 | git clone --bare project2 27 | ``` 28 | 29 | Now we see a new directory `project2.git`. 30 | 31 | 32 | 33 | ## A First Example of Collaboration 34 | 35 | Let's pretend we are a different user. Let's make a directory for our 36 | pretend user and clone our project: 37 | 38 | ```bash 39 | cd ~ 40 | mkdir newuser 41 | cd newuser 42 | git clone ~/project2.git 43 | ``` 44 | 45 | The `clone` command make a new git repo for our user called `project2/` 46 | 47 | If we do a `git log` in it, we'll see the whole history we had from 48 | our earlier work. 49 | 50 | Now, this repo knows where it was cloned from, through a concept 51 | called *remotes*. A remote is a repo (usually a bare repo) that we 52 | communicate with the share our changes (a *push*) of get changes from 53 | other users (a *pull*). We can see our remote by doing: 54 | 55 | ```bash 56 | git remote -v 57 | ``` 58 | 59 | We'll see something like: 60 | 61 | ``` 62 | origin /home/campus.stonybrook.edu/mzingale/project2.git (fetch) 63 | origin /home/campus.stonybrook.edu/mzingale/project2.git (push) 64 | ``` 65 | 66 | Now's let's make a change 67 | 68 | ```{admonition} try it... 69 | add the new user's name to `authors.txt` and commit the change. 70 | ``` 71 | 72 | Now we can share our changes with our remote—the bare repo by doing a *push*. 73 | 74 | ```bash 75 | git push 76 | ``` 77 | 78 | This pushes our changes back to the bare repo. Now go back to our original repo: 79 | 80 | ```bash 81 | cd 82 | cd project2 83 | ``` 84 | 85 | We need to add a remote to this original repo (if you do `git 86 | remote` it will show nothing). We'll add a remote called `origin`. 87 | 88 | ```bash 89 | git remote add origin ~/project2.git 90 | ``` 91 | 92 | Now, we can communicate with the bare repo and get the changes that 93 | the other user made by doing a *pull*: 94 | 95 | ```bash 96 | git pull origin main 97 | ``` 98 | 99 | To make our life easier, we can tell git what remote branch to track: 100 | 101 | ```bash 102 | git branch --set-upstream-to=origin/main main 103 | ``` 104 | 105 | then we can do just 106 | 107 | ```bash 108 | git pull 109 | ``` 110 | 111 | -------------------------------------------------------------------------------- /content/git/github-clone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/git/github-clone.png -------------------------------------------------------------------------------- /content/git/github-copy-ssh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/git/github-copy-ssh.png -------------------------------------------------------------------------------- /content/git/github-create.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/git/github-create.png -------------------------------------------------------------------------------- /content/git/github-fork.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/git/github-fork.png -------------------------------------------------------------------------------- /content/git/github-new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/git/github-new.png -------------------------------------------------------------------------------- /content/git/github-pr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/git/github-pr.png -------------------------------------------------------------------------------- /content/git/github-pr2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/git/github-pr2.png -------------------------------------------------------------------------------- /content/git/github-workflow.odg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/git/github-workflow.odg -------------------------------------------------------------------------------- /content/git/github-workflow.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/git/github-workflow.pdf -------------------------------------------------------------------------------- /content/git/github-workflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/content/git/github-workflow.png -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/docs/.nojekyll -------------------------------------------------------------------------------- /docs/assets/css/ie9.css: -------------------------------------------------------------------------------- 1 | /* 2 | Prism by TEMPLATED 3 | templated.co @templatedco 4 | Released for free under the Creative Commons Attribution 3.0 license (templated.co/license) 5 | */ 6 | 7 | /* Split */ 8 | 9 | .split:after { 10 | content: ''; 11 | display: block; 12 | clear: both; 13 | } 14 | 15 | .split > * { 16 | float: left; 17 | } 18 | 19 | /* Spotlight */ 20 | 21 | .spotlight:after { 22 | content: ''; 23 | display: block; 24 | clear: both; 25 | } 26 | 27 | .spotlight .image { 28 | float: left; 29 | } 30 | 31 | .spotlight .content { 32 | float: left; 33 | } 34 | 35 | /* Banner */ 36 | 37 | #banner { 38 | background: #4A4771; 39 | } -------------------------------------------------------------------------------- /docs/assets/css/images/0101_banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/docs/assets/css/images/0101_banner.png -------------------------------------------------------------------------------- /docs/assets/css/images/overlay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/docs/assets/css/images/overlay.png -------------------------------------------------------------------------------- /docs/assets/css/images/rt_1.5e7_clean2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/docs/assets/css/images/rt_1.5e7_clean2.png -------------------------------------------------------------------------------- /docs/assets/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/docs/assets/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /docs/assets/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/docs/assets/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /docs/assets/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/docs/assets/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/docs/assets/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /docs/assets/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/docs/assets/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /docs/assets/js/ie/html5shiv.js: -------------------------------------------------------------------------------- 1 | /* 2 | HTML5 Shiv v3.6.2 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed 3 | */ 4 | (function(l,f){function m(){var a=e.elements;return"string"==typeof a?a.split(" "):a}function i(a){var b=n[a[o]];b||(b={},h++,a[o]=h,n[h]=b);return b}function p(a,b,c){b||(b=f);if(g)return b.createElement(a);c||(c=i(b));b=c.cache[a]?c.cache[a].cloneNode():r.test(a)?(c.cache[a]=c.createElem(a)).cloneNode():c.createElem(a);return b.canHaveChildren&&!s.test(a)?c.frag.appendChild(b):b}function t(a,b){if(!b.cache)b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag(); 5 | a.createElement=function(c){return!e.shivMethods?b.createElem(c):p(c,a,b)};a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/\w+/g,function(a){b.createElem(a);b.frag.createElement(a);return'c("'+a+'")'})+");return n}")(e,b.frag)}function q(a){a||(a=f);var b=i(a);if(e.shivCSS&&!j&&!b.hasCSS){var c,d=a;c=d.createElement("p");d=d.getElementsByTagName("head")[0]||d.documentElement;c.innerHTML="x"; 6 | c=d.insertBefore(c.lastChild,d.firstChild);b.hasCSS=!!c}g||t(a,b);return a}var k=l.html5||{},s=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,r=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,j,o="_html5shiv",h=0,n={},g;(function(){try{var a=f.createElement("a");a.innerHTML="";j="hidden"in a;var b;if(!(b=1==a.childNodes.length)){f.createElement("a");var c=f.createDocumentFragment();b="undefined"==typeof c.cloneNode|| 7 | "undefined"==typeof c.createDocumentFragment||"undefined"==typeof c.createElement}g=b}catch(d){g=j=!0}})();var e={elements:k.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup main mark meter nav output progress section summary time video",version:"3.6.2",shivCSS:!1!==k.shivCSS,supportsUnknownElements:g,shivMethods:!1!==k.shivMethods,type:"default",shivDocument:q,createElement:p,createDocumentFragment:function(a,b){a||(a=f);if(g)return a.createDocumentFragment(); 8 | for(var b=b||i(a),c=b.frag.cloneNode(),d=0,e=m(),h=e.length;d 0: 36 | for e in args.extras: 37 | print e 38 | -------------------------------------------------------------------------------- /docs/old/examples/ctypes/Makefile: -------------------------------------------------------------------------------- 1 | ALL: cfunc_multid.so 2 | 3 | SOURCES := cfunc_multid.c 4 | OBJECTS := $(SOURCES:.c=.o) 5 | 6 | %.o: %.c 7 | gcc -c -fPIC $< -o $@ 8 | 9 | 10 | cfunc_multid.so: $(OBJECTS) 11 | gcc -shared -o cfunc_multid.so $(OBJECTS) 12 | 13 | -------------------------------------------------------------------------------- /docs/old/examples/ctypes/cfunc_multid.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int my_subroutine(double *iarray, int ilen, int jlen, 4 | double *oarray) { 5 | 6 | /* here iarray and oarray are pointers to a contiguous space in 7 | memory. We wish to access them as 2-d arrays. */ 8 | 9 | /* note: there is no error or bounds checking done here! */ 10 | double *iA[ilen], *oA[ilen]; 11 | 12 | int i; 13 | for (i = 0; i < ilen; i++) { 14 | iA[i] = iarray + i*jlen; 15 | oA[i] = oarray + i*jlen; 16 | } 17 | 18 | 19 | int j; 20 | for (i = 0; i < ilen; i++) { 21 | for (j = 0; j < jlen; j++) { 22 | oA[i][j] = iA[i][j]*iA[i][j]; 23 | } 24 | } 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /docs/old/examples/ctypes/test-ctypes.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import ctypes as C 3 | from numpy.ctypeslib import ndpointer 4 | 5 | # the NumPy way to call this function 6 | 7 | _cfunc = np.ctypeslib.load_library('cfunc_multid', '.') 8 | _cfunc.my_subroutine.restype = C.c_int 9 | _cfunc.my_subroutine.argtypes = [ndpointer(C.c_double, flags="C_CONTIGUOUS"), 10 | C.c_int, C.c_int, 11 | ndpointer(C.c_double, flags="C_CONTIGUOUS")] 12 | 13 | def my_subroutine(A, B): 14 | return _cfunc.my_subroutine(A, C.c_int(A.shape[0]), C.c_int(A.shape[1]), B) 15 | 16 | A = np.arange(20, dtype=np.float64) 17 | A.shape = (4,5) 18 | 19 | 20 | # here we pre-allocate the return array 21 | B = np.zeros_like(A) 22 | 23 | n = my_subroutine(A, B) 24 | 25 | print B 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /docs/old/examples/f2py/Makefile: -------------------------------------------------------------------------------- 1 | ALL: numpy_in_f.so 2 | 3 | numpy_in_f.so: numpy_in_f.f90 4 | f2py --fcompiler=gnu95 -c numpy_in_f.f90 -m numpy_in_f 5 | -------------------------------------------------------------------------------- /docs/old/examples/f2py/numpy_in_f.f90: -------------------------------------------------------------------------------- 1 | subroutine square(a, b, nx, ny) 2 | 3 | implicit none 4 | 5 | integer, intent(in) :: nx, ny 6 | double precision, intent(in) :: a(nx, ny) 7 | double precision, intent(out) :: b(nx, ny) 8 | 9 | !f2py depend(nx, ny) :: a, b 10 | !f2py intent(in) :: a 11 | !f2py intent(out) :: b 12 | 13 | ! call this as b = numpy_in_f.square(a, nx, ny) 14 | 15 | integer :: i, j 16 | 17 | do j = 1, ny 18 | do i = 1, nx 19 | b(i,j) = a(i,j)**2 20 | enddo 21 | enddo 22 | 23 | end subroutine square 24 | -------------------------------------------------------------------------------- /docs/old/examples/f2py/test_f2py.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import numpy_in_f 3 | 4 | a = np.arange(24, dtype=np.float64) 5 | a.shape = (4,6) 6 | 7 | print a.flags 8 | 9 | b = numpy_in_f.square(a, a.shape[0], a.shape[1]) 10 | 11 | print b 12 | 13 | print b.flags 14 | -------------------------------------------------------------------------------- /docs/old/examples/gauss-test.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | import numpy 4 | from gauss import * 5 | from matmul import * 6 | 7 | 8 | # tests of gaussian elimination 9 | 10 | A = numpy.array([ [1, 1, 1], [-1, 2, 0], [2, 0, 1] ], dtype=numpy.float64) 11 | b = numpy.array([6, 3, 5], dtype=numpy.float64) 12 | 13 | # gaussElim changes A in place -- send a copy 14 | x, d = gauss_elim(A.copy(), b.copy(), return_det=1) 15 | 16 | # test it by multiplying A x 17 | bout = mult_Ax(A, x) 18 | 19 | print("matrix A:\n", A) 20 | print("RHS (b): ", b) 21 | print("solved x: ", x) 22 | print("det{A}: ", d) 23 | print("A.x: ", bout) 24 | print(" ") 25 | 26 | A = numpy.array([ [0, 1, 1], [1, 1, 0], [1, 0, 1] ], dtype=numpy.float64) 27 | b = numpy.array([5, 3, 4], dtype=numpy.float64) 28 | x = gauss_elim(A.copy(), b.copy()) 29 | 30 | # test it by multiplying A x 31 | bout = mult_Ax(A, x) 32 | 33 | print("matrix A:\n", A) 34 | print("RHS (b): ", b) 35 | print("solved x: ", x) 36 | print("A.x: ", bout) 37 | print(" ") 38 | 39 | 40 | A = numpy.array([ [0, 0, 0, 4], 41 | [0, 0, 3, 0], 42 | [5, 6, 7, 8], 43 | [0, 4, 3, 2] ], dtype=numpy.float64) 44 | b = numpy.array([5, 4, 9, 1], dtype=numpy.float64) 45 | x = gauss_elim(A.copy(), b.copy()) 46 | 47 | # test it by multiplying A x 48 | bout = mult_Ax(A, x) 49 | 50 | print("matrix A:\n", A) 51 | print("RHS (b): ", b) 52 | print("solved x: ", x) 53 | print("A.x: ", bout) 54 | print(" ") 55 | 56 | 57 | A = numpy.array([ [ 4, 3, 4, 10], 58 | [ 2, -7, 3, 0], 59 | [-2, 11, 1, 3], 60 | [ 3, -4, 0, 2] ], dtype=numpy.float64) 61 | b = numpy.array([2, 6, 3, 1], dtype=numpy.float64) 62 | x = gauss_elim(A.copy(), b.copy()) 63 | 64 | # test it by multiplying A x 65 | bout = mult_Ax(A, x) 66 | 67 | print("matrix A:\n", A) 68 | print("RHS (b): ", b) 69 | print("solved x: ", x) 70 | print("A.x: ", bout) 71 | print(" ") 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /docs/old/examples/getopt_example.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | import getopt 5 | 6 | # simple example of getopt 7 | # 8 | # ./getopt_example.py -a -b # -c string --darg --earg fextra 9 | 10 | try: opts, next = getopt.getopt(sys.argv[1:], "ab:c:", 11 | ["darg", "earg="]) 12 | except getopt.GetoptError: 13 | sys.exit("invalid calling sequence") 14 | 15 | 16 | # set the defaults 17 | a_present = 0 18 | b_value = None 19 | c_value = None 20 | d_present = 0 21 | e_value = None 22 | 23 | for o, a in opts: 24 | if o == "-a": 25 | a_present = 1 26 | elif o == "-b": 27 | b_value = int(a) 28 | elif o == "-c": 29 | c_value = str(a) 30 | elif o == "--darg": 31 | d_present = 1 32 | elif o == "--earg": 33 | e_value = a 34 | 35 | try: extras = next[0:] 36 | except IndexError: 37 | pass 38 | 39 | if a_present: print "-a set" 40 | if not b_value == None: print "b = {}".format(b_value) 41 | if not c_value == None: print "c = {}".format(c_value) 42 | if d_present: print "--darg set" 43 | if not e_value == None: print "e = {}".format(e_value) 44 | 45 | print "extra arguments:" 46 | for e in extras: 47 | print e 48 | 49 | -------------------------------------------------------------------------------- /docs/old/examples/githash.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import string 3 | 4 | # issue the command 'git rev-parse HEAD' 5 | prog = ["git", "rev-parse", "HEAD"] 6 | p0 = subprocess.Popen(prog, stdout=subprocess.PIPE, 7 | stderr=subprocess.PIPE) 8 | stdout0, stderr0 = p0.communicate() 9 | 10 | print "stdout: {}".format(stdout0) 11 | print "stderr: {}".format(stderr0) 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/old/examples/matmul.f90: -------------------------------------------------------------------------------- 1 | program matmul 2 | 3 | ! matrix multiply with OpenMP 4 | ! 5 | ! M. Zingale (2013-04-14) 6 | 7 | integer, parameter :: N = 1000 8 | 9 | double precision a(N,N) 10 | double precision x(N) 11 | double precision b(N) 12 | 13 | integer :: i, j 14 | 15 | ! initialize the matrix and vector 16 | !$omp parallel do private(i, j) 17 | do j = 1, N 18 | do i = 1, N 19 | a(i,j) = dble(i + j) 20 | enddo 21 | enddo 22 | !$omp end parallel do 23 | 24 | do i = 1, N 25 | x(i) = i 26 | enddo 27 | 28 | ! multiply 29 | !$omp parallel do private(i, j) 30 | do i = 1, N 31 | b(i) = 0.0 32 | do j = 1, N 33 | b(i) = b(i) + a(i,j)*x(j) 34 | enddo 35 | enddo 36 | !$end parallel do 37 | 38 | end program matmul 39 | 40 | -------------------------------------------------------------------------------- /docs/old/examples/matmul.py: -------------------------------------------------------------------------------- 1 | # routines for multiplying matrices 2 | 3 | from __future__ import print_function 4 | 5 | import numpy 6 | 7 | def mult_Ax(A, x): 8 | """ return the product of matrix A and vector x: Ax = b """ 9 | 10 | # x is a vector 11 | if not x.ndim == 1: 12 | print("ERROR: x should be a vector") 13 | return None 14 | 15 | N = len(x) 16 | 17 | # A is square, with each dimension of length N 18 | if not A.shape == (N, N): 19 | print("ERROR: A should be square with each dim of same length as x") 20 | return None 21 | 22 | # allocation the product array 23 | b = numpy.zeros((N), dtype=A.dtype) 24 | 25 | # each row of b is the product of the like row of A dotted with 26 | # the vector x 27 | for i in range(N): 28 | b[i] = numpy.dot(A[i,:], x) 29 | 30 | return b 31 | 32 | -------------------------------------------------------------------------------- /docs/old/examples/mayavi-basic.py: -------------------------------------------------------------------------------- 1 | # http://docs.enthought.com/mayavi/mayavi/mlab_case_studies.html 2 | 3 | import numpy as np 4 | 5 | from mayavi import mlab 6 | 7 | x, y, z = np.ogrid[-10:10:20j, -10:10:20j, -10:10:20j] 8 | s = np.sin(x*y*z)/(x*y*z) 9 | 10 | mlab.contour3d(s) 11 | mlab.show() 12 | 13 | # volume rendering 14 | mlab.pipeline.volume(mlab.pipeline.scalar_field(s)) 15 | mlab.show() 16 | 17 | 18 | # change the data limits 19 | mlab.pipeline.volume(mlab.pipeline.scalar_field(s), vmin=0, vmax=0.8) 20 | mlab.show() 21 | 22 | 23 | # cut planes 24 | mlab.pipeline.image_plane_widget(mlab.pipeline.scalar_field(s), 25 | plane_orientation='x_axes', 26 | slice_index=10) 27 | mlab.pipeline.image_plane_widget(mlab.pipeline.scalar_field(s), 28 | plane_orientation='y_axes', 29 | slice_index=10) 30 | mlab.outline() 31 | mlab.show() 32 | 33 | 34 | # combination 35 | src = mlab.pipeline.scalar_field(s) 36 | mlab.pipeline.iso_surface(src, contours=[s.min()+0.1*s.ptp(), ], opacity=0.1) # ptp is the range 37 | mlab.pipeline.iso_surface(src, contours=[s.max()-0.1*s.ptp(), ],) 38 | mlab.pipeline.image_plane_widget(src, 39 | plane_orientation='z_axes', 40 | slice_index=10) 41 | 42 | mlab.show() 43 | -------------------------------------------------------------------------------- /docs/old/examples/mayavi-vector.py: -------------------------------------------------------------------------------- 1 | # http://docs.enthought.com/mayavi/mayavi/mlab_case_studies.html 2 | 3 | import numpy as np 4 | 5 | from mayavi import mlab 6 | 7 | x, y, z = np.mgrid[0:1:20j, 0:1:20j, 0:1:20j] 8 | 9 | u = np.sin(np.pi*x) * np.cos(np.pi*z) 10 | v = -2*np.sin(np.pi*y) * np.cos(2*np.pi*z) 11 | w = np.cos(np.pi*x)*np.sin(np.pi*z) + np.cos(np.pi*y)*np.sin(2*np.pi*z) 12 | 13 | 14 | # a quiver field 15 | mlab.quiver3d(u, v, w) 16 | mlab.outline() 17 | mlab.show() 18 | 19 | 20 | # thin things out -- this doesn't seem to work? 21 | src = mlab.pipeline.vector_field(u, v, w) 22 | #mlab.pipeline.vectors(src, mask_points=20, scale_factor=1.) # keep only one point out of 20 23 | #mlab.outline() 24 | #mlab.show() 25 | 26 | 27 | mlab.pipeline.vector_cut_plane(src, mask_points=2, scale_factor=3) 28 | mlab.outline() 29 | mlab.show() 30 | 31 | 32 | # isosurfaces of the magnitude -- doesn't work 33 | #magnitude = mlab.pipeline.extract_vector_norm(src) 34 | #mlab.pipeline.iso_surface(magnitude, contours=[1.9, 0.5]) 35 | #mlab.outline() 36 | #mlab.show() 37 | 38 | 39 | mlab.figure(fgcolor=(0., 0., 0.), bgcolor=(1, 1, 1)) 40 | src = mlab.pipeline.vector_field(u, v, w) 41 | magnitude = mlab.pipeline.extract_vector_norm(src) 42 | 43 | # We apply the following modules on the magnitude object, in order to 44 | # be able to display the norm of the vectors, eg as the color. 45 | iso = mlab.pipeline.iso_surface(magnitude, contours=[1.9, ], opacity=0.3) 46 | 47 | #vec = mlab.pipeline.vectors(magnitude, mask_points=40, 48 | # line_width=1, 49 | # color=(.8, .8, .8), 50 | # scale_factor=4.) 51 | 52 | flow = mlab.pipeline.streamline(magnitude, seedtype='plane', 53 | seed_visible=False, 54 | seed_scale=0.5, 55 | seed_resolution=1, 56 | linetype='ribbon',) 57 | 58 | vcp = mlab.pipeline.vector_cut_plane(magnitude, mask_points=2, 59 | scale_factor=4, 60 | colormap='jet', 61 | plane_orientation='x_axes') 62 | mlab.show() 63 | 64 | 65 | -------------------------------------------------------------------------------- /docs/old/examples/timing/Makefile: -------------------------------------------------------------------------------- 1 | ALL: laplace_fortran.so laplace_C.so laplace_CAPI.so 2 | 3 | laplace_fortran.so: laplace_fortran.f90 4 | f2py --fcompiler=gnu95 -c laplace_fortran.f90 -m laplace_fortran 5 | 6 | laplace_C.so: laplace_C.c 7 | gcc -c -fPIC laplace_C.c -o laplace_C.o 8 | gcc -shared -o laplace_C.so laplace_C.o 9 | 10 | laplace_CAPI.so: laplace_CAPI.c 11 | python setup.py build_ext --inplace 12 | 13 | 14 | .PHONY: clean 15 | 16 | clean: 17 | rm -f laplace_fortran.so laplace_C.so laplace_CAPI.so 18 | rm -rf build 19 | -------------------------------------------------------------------------------- /docs/old/examples/timing/README: -------------------------------------------------------------------------------- 1 | comparison on Laplacian -------------------------------------------------------------------------------- /docs/old/examples/timing/laplace_C.c: -------------------------------------------------------------------------------- 1 | int C_update(double *iarray, int ilen, int jlen, double dx2, double dy2) { 2 | 3 | 4 | /* here iarray is a pointer to a contiguous space in 5 | memory. We wish to access it as a 2-d array. */ 6 | 7 | /* note: there is no error or bounds checking done here! */ 8 | double *iA[ilen]; 9 | 10 | int i; 11 | for (i = 0; i < ilen; i++) { 12 | iA[i] = iarray + i*jlen; 13 | } 14 | 15 | 16 | int j; 17 | for (i = 1; i < ilen-1; i++) { 18 | for (j = 1; j < jlen-1; j++) { 19 | iA[i][j] = ( (iA[i+1][j] + iA[i-1][j])*dy2 + 20 | (iA[i][j+1] + iA[i][j-1])*dx2 ) / 21 | (2.0*(dx2 + dy2)); 22 | } 23 | } 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /docs/old/examples/timing/laplace_CAPI.c: -------------------------------------------------------------------------------- 1 | /* see 2 | http://wiki.scipy.org/Cookbook/C_Extensions/NumPy_arrays and 3 | http://scipy-lectures.github.io/advanced/interfacing_with_c/interfacing_with_c.html 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | 10 | /* a static function in C limits its scope to this file -- the linker 11 | won't complain about clashes */ 12 | static PyObject* CAPI_update(PyObject* self, PyObject* args) 13 | { 14 | 15 | PyArrayObject *iarray; 16 | double **iA; 17 | int i, j, m, n; 18 | double dx2, dy2; 19 | 20 | /* parse the inputs -- we need to know what the arguments of our 21 | call were. We'll assume: 22 | 23 | ex_function(array, dx2, dy2) 24 | 25 | and array is updated in place 26 | */ 27 | 28 | if (!PyArg_ParseTuple(args, "O!dd", 29 | &PyArray_Type, &iarray, &dx2, &dy2)) return NULL; 30 | if (NULL == iarray) return NULL; 31 | 32 | /* check to make sure we are a double type */ 33 | if (iarray->descr->type_num != NPY_DOUBLE || 34 | iarray->nd != 2) { 35 | PyErr_SetString(PyExc_ValueError, "wrong input array type"); 36 | return NULL; 37 | } 38 | 39 | /* get the dimensions */ 40 | n = iarray->dimensions[0]; 41 | m = iarray->dimensions[1]; 42 | 43 | /* change contigous arrays into C ** arrays -- we need to have a 44 | vector of pointers that point to the correct location in the 45 | contiguous block of memory that stores the multi-dimensional 46 | array data */ 47 | iA = (double **) malloc( (size_t) (n*sizeof(double))); 48 | for (i = 0; i < n; i++) { 49 | iA[i] = (double *) iarray->data + i*m; 50 | } 51 | 52 | /* now we can do our manipulation */ 53 | for (i = 1; i < n-1; i++) { 54 | for (j = 1; j < m-1; j++) { 55 | iA[i][j] = ( (iA[i+1][j] + iA[i-1][j])*dy2 + 56 | (iA[i][j+1] + iA[i][j-1])*dx2 ) / 57 | (2.0*(dx2 + dy2)); 58 | } 59 | } 60 | 61 | 62 | /* free up the memory we allocated for the array indexing */ 63 | free (iA); 64 | 65 | /* even though we are returning an integer, it is a Python object */ 66 | return Py_BuildValue("d", 0); 67 | 68 | } 69 | 70 | 71 | /* this is the table for function names that Python will see */ 72 | static PyMethodDef laplace_CAPIMethods[] = { 73 | {"CAPI_update", CAPI_update, METH_VARARGS, "Laplace G-S update in pure C"}, 74 | {NULL, NULL, 0, NULL} 75 | }; 76 | 77 | /* this tells python what to do when it first imports this module -- 78 | the name follows directly from the table name above */ 79 | PyMODINIT_FUNC initlaplace_CAPI(void) { 80 | (void) Py_InitModule("laplace_CAPI", laplace_CAPIMethods); 81 | import_array(); // this deals with the NumPy stuff 82 | } 83 | -------------------------------------------------------------------------------- /docs/old/examples/timing/laplace_cython.pyx: -------------------------------------------------------------------------------- 1 | #cython: boundscheck=False 2 | #cython: wraparound=False 3 | 4 | cimport numpy as np 5 | 6 | def cy_update(np.ndarray[double, ndim=2] u, double dx2, double dy2): 7 | cdef unsigned int i, j 8 | for i in xrange(1,u.shape[0]-1): 9 | for j in xrange(1, u.shape[1]-1): 10 | u[i,j] = ((u[i+1, j] + u[i-1, j]) * dy2 + 11 | (u[i, j+1] + u[i, j-1]) * dx2) / (2*(dx2+dy2)) 12 | -------------------------------------------------------------------------------- /docs/old/examples/timing/laplace_fortran.f90: -------------------------------------------------------------------------------- 1 | subroutine f90_update(u, nx, ny, dx2, dy2) 2 | 3 | implicit none 4 | 5 | integer, intent(in) :: nx, ny 6 | double precision, intent(inout) :: u(nx, ny) 7 | double precision, intent(in) :: dx2, dy2 8 | 9 | !f2py depend(nx, ny) :: u 10 | !f2py intent(inout) :: u 11 | !f2py intent(in) :: dx2, dy2 12 | 13 | integer :: i, j 14 | 15 | do j = 2, ny-1 16 | do i = 2, nx-1 17 | u(i,j) = ( (u(i+1,j) + u(i-1,j))*dy2 + (u(i,j+1) + u(i,j-1))*dx2 ) / & 18 | (2.0d0*(dx2 + dy2)) 19 | enddo 20 | enddo 21 | 22 | end subroutine f90_update 23 | -------------------------------------------------------------------------------- /docs/old/examples/timing/setup.py: -------------------------------------------------------------------------------- 1 | from distutils.core import setup, Extension 2 | import numpy 3 | 4 | # define the extension module 5 | laplace_CAPI = Extension('laplace_CAPI', sources=['laplace_CAPI.c'], 6 | include_dirs=[numpy.get_include()]) #, 7 | # define_macros=[("NPY_NO_DEPRECATED_API", "NPY_1_7_API_VERSION")]) 8 | 9 | # run the setup 10 | setup(ext_modules=[laplace_CAPI]) 11 | 12 | -------------------------------------------------------------------------------- /docs/old/lectures/VARDEN-tests.ini: -------------------------------------------------------------------------------- 1 | [main] 2 | boxLibDir = /home/regtester/RegTesting/BoxLib/ 3 | sourceDir = /home/regtester/RegTesting/VARDEN/ 4 | testTopDir = /home/regtester/RegTesting/rt-VARDEN/ 5 | webTopDir = /home/regtester/RegTesting/rt-VARDEN/web 6 | compareToolDir = /home/regtester/RegTesting/AmrPostprocessing/F_Src 7 | 8 | MAKE = make 9 | sourceTree = F_Src 10 | numMakeJobs = 8 11 | 12 | COMP = g++ 13 | FCOMP = gfortran 14 | 15 | # suiteName is the name prepended to all output directories 16 | suiteName = VARDEN 17 | 18 | reportActiveTestsOnly = 1 19 | 20 | # Add "GO UP" link at the top of the web page? 21 | goUpLink = 1 22 | 23 | 24 | # MPIcommand should use the placeholders: 25 | # @host@ to indicate where to put the hostname to run on 26 | # @nprocs@ to indicate where to put the number of processors 27 | # @command@ to indicate where to put the command to run 28 | # 29 | # only tests with useMPI = 1 will run in parallel 30 | # nprocs is problem dependent and specified in the individual problem 31 | # sections. 32 | 33 | #MPIcommand = mpiexec -host @host@ -n @nprocs@ @command@ 34 | MPIcommand = /usr/local/bin/mpiexec -n @nprocs@ @command@ 35 | MPIhost = 36 | 37 | # individual problems follow 38 | 39 | [bubble-2d] 40 | buildDir = varden/test 41 | inputFile = inputs_2d-regt 42 | dim = 2 43 | restartTest = 0 44 | useMPI = 1 45 | numprocs = 2 46 | useOMP = 0 47 | numthreads = 2 48 | compileTest = 0 49 | doVis = 0 50 | 51 | [bubble-3d] 52 | buildDir = varden/test 53 | inputFile = inputs_3d-regt 54 | dim = 3 55 | restartTest = 0 56 | useMPI = 1 57 | numprocs = 3 58 | useOMP = 1 59 | numthreads = 2 60 | compileTest = 0 61 | doVis = 0 62 | 63 | [bubble-restart] 64 | buildDir = varden/test 65 | inputFile = inputs-restart-regt 66 | dim = 3 67 | restartTest = 1 68 | restartFileNum = 4 69 | useMPI = 1 70 | numprocs = 3 71 | useOMP = 1 72 | numthreads = 2 73 | compileTest = 0 74 | doVis = 0 75 | -------------------------------------------------------------------------------- /docs/old/lectures/extensions.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/docs/old/lectures/extensions.pdf -------------------------------------------------------------------------------- /docs/old/lectures/gui.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/docs/old/lectures/gui.pdf -------------------------------------------------------------------------------- /docs/old/lectures/matplotlib.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/docs/old/lectures/matplotlib.pdf -------------------------------------------------------------------------------- /docs/old/lectures/mayavi.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/docs/old/lectures/mayavi.pdf -------------------------------------------------------------------------------- /docs/old/lectures/numpy.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/docs/old/lectures/numpy.pdf -------------------------------------------------------------------------------- /docs/old/lectures/packaging.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/docs/old/lectures/packaging.pdf -------------------------------------------------------------------------------- /docs/old/lectures/profile.py: -------------------------------------------------------------------------------- 1 | """ 2 | A very simple profiling class. Define some timers and methods 3 | to start and stop them. Nesting of timers is tracked so we can 4 | pretty print the profiling information. 5 | 6 | # define a timer object, labeled 'my timer' 7 | a = timer('my timer') 8 | 9 | This will add 'my timer' to the list of keys in the 'my timer' 10 | dictionary. Subsequent calls to the timer class constructor 11 | will have no effect. 12 | 13 | # start timing the 'my timer' block of code 14 | a.begin() 15 | 16 | ... do stuff here ... 17 | 18 | # end the timing of the 'my timer' block of code 19 | a.end() 20 | 21 | for best results, the block of code timed should be large 22 | enough to offset the overhead of the timer class method 23 | calls. 24 | 25 | Multiple timers can be instanciated and nested. The stackCount 26 | global parameter keeps count of the level of nesting, and the 27 | timerNesting data structure stores the nesting level for each 28 | defined timer. 29 | 30 | timeReport() is called at the end to print out a summary of the 31 | timing. 32 | 33 | At present, no enforcement is done to ensure proper nesting. 34 | 35 | """ 36 | 37 | 38 | import time 39 | 40 | timers = {} 41 | 42 | # keep basic count of how nested we are in the timers, so we can do some 43 | # pretty printing. 44 | stackCount = 0 45 | 46 | timerNesting = {} 47 | timerOrder = [] 48 | 49 | class timer: 50 | 51 | def __init__ (self, name): 52 | global timers, stackCount, timerNesting, timerOrder 53 | 54 | self.name = name 55 | 56 | keys = timers.keys() 57 | 58 | if name not in keys: 59 | timers[name] = 0.0 60 | self.startTime = 0.0 61 | timerOrder.append(name) 62 | timerNesting[name] = stackCount 63 | 64 | 65 | def begin(self): 66 | global stackCount 67 | 68 | self.startTime = time.time() 69 | stackCount += 1 70 | 71 | 72 | def end(self): 73 | global timers, stackCount 74 | 75 | elapsedTime = time.time() - self.startTime 76 | timers[self.name] += elapsedTime 77 | 78 | stackCount -= 1 79 | 80 | 81 | def timeReport(): 82 | global timers, timerOrder, timerNesting 83 | 84 | spacing = ' ' 85 | for key in timerOrder: 86 | print timerNesting[key]*spacing + key + ': ', timers[key] 87 | 88 | 89 | 90 | if __name__ == "__main__": 91 | a = timer('1') 92 | a.begin() 93 | time.sleep(10.) 94 | a.end() 95 | 96 | b = timer('2') 97 | b.begin() 98 | time.sleep(5.) 99 | 100 | c = timer('3') 101 | c.begin() 102 | 103 | time.sleep(20.) 104 | 105 | b.end() 106 | c.end() 107 | 108 | timeReport() 109 | 110 | -------------------------------------------------------------------------------- /docs/old/lectures/python-practices.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/docs/old/lectures/python-practices.pdf -------------------------------------------------------------------------------- /docs/old/lectures/python.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/docs/old/lectures/python.pdf -------------------------------------------------------------------------------- /docs/old/lectures/scipy.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/docs/old/lectures/scipy.pdf -------------------------------------------------------------------------------- /docs/old/lectures/shopping.csv: -------------------------------------------------------------------------------- 1 | item,quantity,unit price,total 2 | apples,2,0.33,0.66 3 | bananas,5,0.1,0.5 4 | milk,1,2.5,2.5 5 | soda,3,1,3 6 | rolls,12,0.33,3.96 7 | eggs,1,2.5,2.5 8 | -------------------------------------------------------------------------------- /docs/old/lectures/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/docs/old/lectures/test.png -------------------------------------------------------------------------------- /docs/old/lectures/test.txt: -------------------------------------------------------------------------------- 1 | Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do 2 | eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad 3 | minim veniam, quis nostrud exercitation ullamco laboris nisi ut 4 | aliquip ex ea commodo consequat. Duis aute irure dolor in 5 | reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla 6 | pariatur. Excepteur sint occaecat cupidatat non proident, sunt in 7 | culpa qui officia deserunt mollit anim id est laborum. 8 | 9 | -------------------------------------------------------------------------------- /docs/old/lectures/testing.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/docs/old/lectures/testing.pdf -------------------------------------------------------------------------------- /docs/old/python.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/docs/old/python.png -------------------------------------------------------------------------------- /examples/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.so 3 | *~ 4 | -------------------------------------------------------------------------------- /examples/GUI/NOTES: -------------------------------------------------------------------------------- 1 | Basic intro: 2 | http://sebsauvage.net/python/gui/ 3 | 4 | Nice example of a phonelist app: 5 | http://www.openbookproject.net/py4fun/gui/tkPhone.html 6 | 7 | Layouts: 8 | http://zetcode.com/gui/tkinter/layout/ 9 | 10 | 11 | sympy evaluate: 12 | 13 | from sympy.parsing.sympy_parser import parse_expr 14 | a = sympy.parse_expr("1+x", evaluate=0) 15 | from sympy.abc import x 16 | print a.evalf(subs={x:1}) 17 | 18 | 19 | 20 | -- doing everything as a class: 21 | 22 | http://programmers.stackexchange.com/questions/213935/why-use-classes-when-programming-a-tkinter-gui-in-python -------------------------------------------------------------------------------- /examples/GUI/event-example.py: -------------------------------------------------------------------------------- 1 | # a simple example of an event loop that implements a CLI inventory 2 | # system 3 | # 4 | # requires python 3 5 | 6 | import sys 7 | 8 | help_str = """ 9 | {h, help} : show this help 10 | {a, add} item quantity : add a quantity of item to inventory 11 | {r, remove} item quantity : remove a quantity of item from inventory 12 | {l, list} : list the inventory 13 | {q, quit} : quit 14 | """ 15 | 16 | inventory = {} 17 | 18 | while True: 19 | 20 | a = input("\nCommand (or Enter 'h' for help)\n>> ") 21 | 22 | parts = a.split() 23 | cmd = parts.pop(0) 24 | 25 | if cmd in ["h", "help"]: 26 | print(help_str) 27 | 28 | elif cmd in ["a", "add"]: 29 | if not len(parts) == 2: 30 | print("invalid add") 31 | else: 32 | if not parts[0] in inventory.keys(): 33 | inventory[parts[0]] = int(parts[1]) 34 | else: 35 | inventory[parts[0]] += int(parts[1]) 36 | 37 | elif cmd in ["r", "remove"]: 38 | if not len(parts) == 2: 39 | print("invalid remove") 40 | else: 41 | if not parts[0] in inventory.keys(): 42 | print("unable to remove -- no items in inventory") 43 | else: 44 | inventory[parts[0]] -= int(parts[1]) 45 | 46 | elif cmd in ["l", "list"]: 47 | for k, v in inventory.items(): 48 | print("{:30} {:10}".format(k, v)) 49 | 50 | elif cmd in ["q", "quit"]: 51 | sys.exit() 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /examples/GUI/parse.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import sympy 3 | from sympy.abc import x 4 | from sympy.parsing.sympy_parser import parse_expr 5 | 6 | fstr = input("f(x) = ") 7 | 8 | a = parse_expr(fstr, evaluate=0) 9 | 10 | f = sympy.lambdify(x, a, "numpy") 11 | 12 | x = np.linspace(0,1,100) 13 | 14 | print(f(x)) 15 | -------------------------------------------------------------------------------- /examples/commandline/argparse_example.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # to get usage: use -h 4 | import argparse 5 | 6 | # simple example of argparse 7 | 8 | parser = argparse.ArgumentParser() 9 | parser.add_argument("-a", help="the -a option", action="store_true") 10 | parser.add_argument("-b", help="-b takes a number", type=int, default=0) 11 | parser.add_argument("-c", help="-c takes a string", type=str, default=None) 12 | parser.add_argument("--darg", help="the --darg option", action="store_true") 13 | parser.add_argument("--earg", help="--earg takes a string", type=str, metavar="test", 14 | default="example string") 15 | 16 | # extra arguments (positional) 17 | parser.add_argument("extras", metavar="extra", type=str, nargs="*", 18 | help="optional positional arguments") 19 | 20 | args = parser.parse_args() 21 | 22 | if args.a: 23 | print("-a set") 24 | print(f"-b = {args.b}") 25 | print(f"-c = {args.c}") 26 | if args.darg: 27 | print("--dargs set") 28 | print(f"--earg value = {args.earg}") 29 | 30 | print(" ") 31 | print("extra positional arguments: ") 32 | if len(args.extras) > 0: 33 | for e in args.extras: 34 | print(e) 35 | -------------------------------------------------------------------------------- /examples/extensions-old/C-API/README: -------------------------------------------------------------------------------- 1 | This example for using the C-API with NumPy is for python 3.x only -- 2 | the interface for python 2.x is different. Note that this was written 3 | to use the latest API. 4 | 5 | reference: http://scipy-lectures.github.io/advanced/interfacing_with_c/interfacing_with_c.html 6 | http://wiki.scipy.org/Cookbook/C_Extensions/NumPy_arrays 7 | 8 | to build: 9 | 10 | python3 setup.py build_ext --inplace 11 | 12 | to run: 13 | 14 | >>> import numpy_in_c 15 | >>> help (numpy_in_c) 16 | 17 | >>> import numpy as np 18 | 19 | >>> a = np.arange(20, dtype=np.float64) 20 | >>> a.shape = (4,5) 21 | >>> print a 22 | [[ 0. 1. 2. 3. 4.] 23 | [ 5. 6. 7. 8. 9.] 24 | [ 10. 11. 12. 13. 14.] 25 | [ 15. 16. 17. 18. 19.]] 26 | 27 | >>> b = numpy_in_c.example(a) 28 | >>> print b 29 | [[ 0. 1. 4. 9. 16.] 30 | [ 25. 36. 49. 64. 81.] 31 | [ 100. 121. 144. 169. 196.] 32 | [ 225. 256. 289. 324. 361.]] 33 | 34 | 35 | -------------------------------------------------------------------------------- /examples/extensions-old/C-API/setup.py: -------------------------------------------------------------------------------- 1 | from distutils.core import setup, Extension 2 | import numpy 3 | 4 | # define the extension module 5 | numpy_in_c = Extension('numpy_in_c', sources=['numpy-ex.c'], 6 | include_dirs=[numpy.get_include()]) #, 7 | # define_macros=[("NPY_NO_DEPRECATED_API", "NPY_1_7_API_VERSION")]) 8 | 9 | # run the setup 10 | setup(ext_modules=[numpy_in_c]) 11 | -------------------------------------------------------------------------------- /examples/extensions-old/C-API/test-C-API.py: -------------------------------------------------------------------------------- 1 | import numpy_in_c 2 | import numpy as np 3 | 4 | a = np.arange(20, dtype=np.float64) 5 | a.shape = (4,5) 6 | print(a) 7 | 8 | b = numpy_in_c.example(a) 9 | print(b) 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /examples/extensions-old/Cython/laplace/README: -------------------------------------------------------------------------------- 1 | This is an example from http://technicaldiscovery.blogspot.com/2011/06/speeding-up-python-numpy-cython-and.html 2 | 3 | To use: 4 | 5 | python setup.py build_ext --inplace 6 | -------------------------------------------------------------------------------- /examples/extensions-old/Cython/laplace/laplace.pyx: -------------------------------------------------------------------------------- 1 | cimport numpy as np 2 | 3 | def cy_update(np.ndarray[double, ndim=2] u, double dx2, double dy2): 4 | cdef unsigned int i, j 5 | for i in xrange(1,u.shape[0]-1): 6 | for j in xrange(1, u.shape[1]-1): 7 | u[i,j] = ((u[i+1, j] + u[i-1, j]) * dy2 + 8 | (u[i, j+1] + u[i, j-1]) * dx2) / (2*(dx2+dy2)) 9 | 10 | 11 | -------------------------------------------------------------------------------- /examples/extensions-old/Cython/laplace/setup.py: -------------------------------------------------------------------------------- 1 | from distutils.core import setup 2 | from distutils.extension import Extension 3 | from Cython.Distutils import build_ext 4 | 5 | import numpy 6 | 7 | ext = Extension("laplace", ["laplace.pyx"], 8 | include_dirs = [numpy.get_include()]) 9 | 10 | setup(ext_modules=[ext], 11 | cmdclass = {'build_ext': build_ext}) 12 | -------------------------------------------------------------------------------- /examples/extensions-old/Cython/laplace/test_cy.py: -------------------------------------------------------------------------------- 1 | # example from: http://technicaldiscovery.blogspot.com/2011/06/speeding-up-python-numpy-cython-and.html 2 | from numpy import zeros 3 | import laplace 4 | 5 | import time 6 | 7 | dx = 0.1 8 | dy = 0.1 9 | dx2 = dx*dx 10 | dy2 = dy*dy 11 | 12 | 13 | # pure python version 14 | def py_update(u): 15 | nx, ny = u.shape 16 | for i in range(1,nx-1): 17 | for j in range(1, ny-1): 18 | u[i,j] = ((u[i+1, j] + u[i-1, j]) * dy2 + 19 | (u[i, j+1] + u[i, j-1]) * dx2) / (2*(dx2+dy2)) 20 | 21 | 22 | # general interface to do Niter iterations 23 | def calc(N, Niter=100, func=py_update, args=()): 24 | u = zeros([N, N]) 25 | u[0] = 1 # this is a boundary condition 26 | for i in range(Niter): 27 | func(u,*args) 28 | return u 29 | 30 | # python version 31 | start = time.time() 32 | 33 | res_py = calc(64) 34 | 35 | print("pure python: ", time.time() - start) 36 | 37 | 38 | start = time.time() 39 | 40 | res_cy = calc(64, func=laplace.cy_update, args=(dx2, dy2) ) 41 | 42 | print("cython: ", time.time() - start) 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /examples/extensions-old/Cython/square/setup.py: -------------------------------------------------------------------------------- 1 | from distutils.core import setup 2 | from distutils.extension import Extension 3 | from Cython.Distutils import build_ext 4 | 5 | import numpy 6 | 7 | ext = Extension("square", ["square.pyx"], 8 | include_dirs = [numpy.get_include()]) 9 | 10 | setup(ext_modules=[ext], 11 | cmdclass = {'build_ext': build_ext}) 12 | -------------------------------------------------------------------------------- /examples/extensions-old/Cython/square/square.pyx: -------------------------------------------------------------------------------- 1 | cimport numpy as np 2 | import numpy as np 3 | 4 | #cython: boundscheck=False 5 | #cython: wraparound=False 6 | 7 | def cy_square(np.ndarray[double, ndim=2] A): 8 | 9 | # in Cython, we should use cdef to declare the types of the variables 10 | # this helps with generating the C code 11 | cdef int nx = A.shape[0] 12 | cdef int ny = A.shape[1] 13 | 14 | # return array -- we allocate it much like in straight NumPy 15 | cdef np.ndarray B = np.zeros( (nx, ny), dtype=np.float64) 16 | 17 | cdef int i, j 18 | for i in range(nx): 19 | for j in range(ny): 20 | B[i,j] = A[i,j]**2 21 | 22 | return B 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /examples/extensions-old/Cython/square/test_cy.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import square 3 | 4 | import time 5 | 6 | N = 400 7 | M = 600 8 | 9 | A = np.arange(M*N, dtype=np.float64) 10 | A.shape = (N,M) 11 | 12 | # python version (note: this is a simple example, so doing B = A**2 13 | # will be faster than any of these methods) 14 | start = time.time() 15 | 16 | B = np.zeros_like(A) 17 | 18 | for i in range(A.shape[0]): 19 | for j in range(A.shape[1]): 20 | B[i,j] = A[i,j]**2 21 | 22 | 23 | print("pure python: ", time.time() - start) 24 | 25 | start = time.time() 26 | B = A**2 27 | print("numpy: ", time.time() - start) 28 | 29 | 30 | # using our Cython routine 31 | start = time.time() 32 | 33 | B_cy = square.cy_square(A) 34 | 35 | print("cython: ", time.time() - start) 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /examples/extensions-old/ctypes/multi-d/Makefile: -------------------------------------------------------------------------------- 1 | ALL: cfunc_multid.so 2 | 3 | SOURCES := cfunc_multid.c 4 | OBJECTS := $(SOURCES:.c=.o) 5 | 6 | %.o: %.c 7 | gcc -c -fPIC $< -o $@ 8 | 9 | 10 | cfunc_multid.so: $(OBJECTS) 11 | gcc -shared -o cfunc_multid.so $(OBJECTS) 12 | 13 | -------------------------------------------------------------------------------- /examples/extensions-old/ctypes/multi-d/README: -------------------------------------------------------------------------------- 1 | compiling: 2 | 3 | gcc -c -fPIC cfunc.c -o cfunc.o 4 | gcc -shared -o cfunc.so cfunc.o 5 | 6 | based on: 7 | 8 | http://stackoverflow.com/questions/145270/calling-c-c-from-python 9 | http://wiki.scipy.org/Cookbook/Ctypes 10 | -------------------------------------------------------------------------------- /examples/extensions-old/ctypes/multi-d/cfunc_multid.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int my_subroutine(double *iarray, int ilen, int jlen, 4 | double *oarray) { 5 | 6 | /* here iarray and oarray are pointers to a contiguous space in 7 | memory. We wish to access them as 2-d arrays. */ 8 | 9 | /* note: there is no error or bounds checking done here! */ 10 | double *iA[ilen], *oA[ilen]; 11 | 12 | int i; 13 | for (i = 0; i < ilen; i++) { 14 | iA[i] = iarray + i*jlen; 15 | oA[i] = oarray + i*jlen; 16 | } 17 | 18 | 19 | int j; 20 | for (i = 0; i < ilen; i++) { 21 | for (j = 0; j < jlen; j++) { 22 | oA[i][j] = iA[i][j]*iA[i][j]; 23 | } 24 | } 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /examples/extensions-old/ctypes/multi-d/test-ctypes.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import ctypes as C 3 | from numpy.ctypeslib import ndpointer 4 | 5 | # the NumPy way to call this function 6 | 7 | _cfunc = np.ctypeslib.load_library('cfunc_multid', '.') 8 | _cfunc.my_subroutine.restype = C.c_int 9 | _cfunc.my_subroutine.argtypes = [ndpointer(C.c_double, flags="C_CONTIGUOUS"), 10 | C.c_int, C.c_int, 11 | ndpointer(C.c_double, flags="C_CONTIGUOUS")] 12 | 13 | def my_subroutine(A, B): 14 | return _cfunc.my_subroutine(A, C.c_int(A.shape[0]), C.c_int(A.shape[1]), B) 15 | 16 | A = np.arange(20, dtype=np.float64) 17 | A.shape = (4,5) 18 | 19 | 20 | # here we pre-allocate the return array 21 | B = np.zeros_like(A) 22 | 23 | n = my_subroutine(A, B) 24 | 25 | print(B) 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /examples/extensions-old/ctypes/multi-d/test_multid.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import ctypes as C 3 | 4 | _cfunc = np.ctypeslib.load_library('cfunc_multid', '.') 5 | _cfunc.my_subroutine.restype = C.c_int 6 | _cfunc.my_subroutine.argtypes = [C.POINTER(C.c_double), C.c_int, C.c_int, C.POINTER(C.c_double)] 7 | 8 | def my_subroutine(A, B): 9 | return _cfunc.my_subroutine(A.ctypes.data_as(C.POINTER(C.c_double)), 10 | C.c_int(A.shape[0]), C.c_int(A.shape[1]), 11 | B.ctypes.data_as(C.POINTER(C.c_double))) 12 | 13 | A = np.arange(20, dtype=np.float64) 14 | A.shape = (4,5) 15 | 16 | 17 | # here we pre-allocate the return array 18 | B = np.zeros_like(A) 19 | 20 | n = my_subroutine(A, B) 21 | 22 | print(B) 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /examples/extensions-old/ctypes/simple/Makefile: -------------------------------------------------------------------------------- 1 | ALL: cfunc.so 2 | 3 | SOURCES := cfunc.c 4 | OBJECTS := $(SOURCES:.c=.o) 5 | 6 | %.o: %.c 7 | gcc -c -fPIC $< -o $@ 8 | 9 | 10 | cfunc.so: $(OBJECTS) 11 | gcc -shared -o cfunc.so $(OBJECTS) 12 | 13 | -------------------------------------------------------------------------------- /examples/extensions-old/ctypes/simple/README: -------------------------------------------------------------------------------- 1 | compiling: 2 | 3 | gcc -c -fPIC cfunc.c -o cfunc.o 4 | gcc -shared -o cfunc.so cfunc.o 5 | 6 | based on: 7 | 8 | http://stackoverflow.com/questions/145270/calling-c-c-from-python 9 | http://wiki.scipy.org/Cookbook/Ctypes 10 | -------------------------------------------------------------------------------- /examples/extensions-old/ctypes/simple/cfunc.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int my_subroutine(double *array, int len) { 4 | 5 | printf("in my_subroutine\n"); 6 | 7 | int i; 8 | for (i = 0; i < len; i++) { 9 | printf("%3d: %f\n", i, array[i]); 10 | } 11 | 12 | return 0; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /examples/extensions-old/ctypes/simple/numpy-example.py: -------------------------------------------------------------------------------- 1 | # see https://docs.scipy.org/doc/numpy/reference/routines.ctypeslib.html 2 | 3 | import numpy as np 4 | import numpy.ctypeslib as npc 5 | import ctypes as C 6 | 7 | # load our extension -- this returns a ctypes library object 8 | cfunc = npc.load_library('cfunc', '.') 9 | 10 | # set the return type 11 | cfunc.my_subroutine.restype = C.c_int 12 | 13 | # set the argument types 14 | cfunc.my_subroutine.argtypes = [npc.ndpointer(C.c_double, flags="C_CONTIGUOUS"), 15 | C.c_int] 16 | 17 | def my_subroutine(A): 18 | return cfunc.my_subroutine(A, len(A)) 19 | 20 | A = np.arange(10, dtype=np.float64) 21 | n = my_subroutine(A) 22 | 23 | 24 | -------------------------------------------------------------------------------- /examples/extensions-old/ctypes/simple/pointer-example.py: -------------------------------------------------------------------------------- 1 | # this version of the driver uses the normal ctypes POINTER(), so you 2 | # need to have your numpy array make itself appear as a C pointer 3 | # explicitly. 4 | 5 | import numpy as np 6 | import ctypes as C 7 | 8 | # load our extension -- this returns a ctypes library object 9 | cfunc = np.ctypeslib.load_library('cfunc', '.') 10 | 11 | # set the return type 12 | cfunc.my_subroutine.restype = C.c_int 13 | 14 | # set the argument types 15 | cfunc.my_subroutine.argtypes = [C.POINTER(C.c_double), 16 | C.c_int] 17 | 18 | def my_subroutine(A): 19 | return cfunc.my_subroutine(A.ctypes.data_as(C.POINTER(C.c_double)), len(A)) 20 | 21 | A = np.arange(10, dtype=np.float64) 22 | n = my_subroutine(A) 23 | 24 | 25 | -------------------------------------------------------------------------------- /examples/extensions-old/f2py/Makefile: -------------------------------------------------------------------------------- 1 | ALL: numpy_in_f.so 2 | 3 | numpy_in_f.so: numpy_in_f.f90 4 | f2py3 --fcompiler=gnu95 -c numpy_in_f.f90 -m numpy_in_f 5 | -------------------------------------------------------------------------------- /examples/extensions-old/f2py/numpy_in_f.f90: -------------------------------------------------------------------------------- 1 | subroutine square(a, b, nx, ny) 2 | 3 | implicit none 4 | 5 | integer, intent(in) :: nx, ny 6 | double precision, intent(in) :: a(nx, ny) 7 | double precision, intent(out) :: b(nx, ny) 8 | 9 | !f2py depend(nx, ny) :: a, b 10 | !f2py intent(in) :: a 11 | !f2py intent(out) :: b 12 | 13 | ! call this as b = numpy_in_f.square(a, nx, ny) 14 | 15 | integer :: i, j 16 | 17 | do j = 1, ny 18 | do i = 1, nx 19 | b(i,j) = a(i,j)**2 20 | enddo 21 | enddo 22 | 23 | end subroutine square 24 | -------------------------------------------------------------------------------- /examples/extensions-old/f2py/test_f2py.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import numpy_in_f 3 | 4 | a = np.arange(24, dtype=np.float64) 5 | a.shape = (4,6) 6 | 7 | print(a.flags) 8 | 9 | b = numpy_in_f.square(a, a.shape[0], a.shape[1]) 10 | 11 | print(b) 12 | 13 | print(b.flags) 14 | 15 | -------------------------------------------------------------------------------- /examples/extensions-old/timing/Makefile: -------------------------------------------------------------------------------- 1 | ALL: laplace_fortran.so laplace_C.so laplace_CAPI.so 2 | 3 | laplace_fortran.so: laplace_fortran.f90 4 | f2py3 --fcompiler=gnu95 -c laplace_fortran.f90 -m laplace_fortran 5 | 6 | laplace_C.so: laplace_C.c 7 | gcc -c -fPIC laplace_C.c -o laplace_C.o 8 | gcc -shared -o laplace_C.so laplace_C.o 9 | 10 | laplace_CAPI.so: laplace_CAPI.c 11 | python3 setup.py build_ext --inplace 12 | 13 | 14 | .PHONY: clean 15 | 16 | clean: 17 | rm -f laplace_fortran.so laplace_C.so laplace_CAPI.so 18 | rm -rf build 19 | -------------------------------------------------------------------------------- /examples/extensions-old/timing/README: -------------------------------------------------------------------------------- 1 | comparison on Laplacian -------------------------------------------------------------------------------- /examples/extensions-old/timing/laplace_C.c: -------------------------------------------------------------------------------- 1 | int C_update(double *iarray, int ilen, int jlen, double dx2, double dy2) { 2 | 3 | 4 | /* here iarray is a pointer to a contiguous space in 5 | memory. We wish to access it as a 2-d array. */ 6 | 7 | /* note: there is no error or bounds checking done here! */ 8 | double *iA[ilen]; 9 | 10 | int i; 11 | for (i = 0; i < ilen; i++) { 12 | iA[i] = iarray + i*jlen; 13 | } 14 | 15 | 16 | int j; 17 | for (i = 1; i < ilen-1; i++) { 18 | for (j = 1; j < jlen-1; j++) { 19 | iA[i][j] = ( (iA[i+1][j] + iA[i-1][j])*dy2 + 20 | (iA[i][j+1] + iA[i][j-1])*dx2 ) / 21 | (2.0*(dx2 + dy2)); 22 | } 23 | } 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /examples/extensions-old/timing/laplace_CAPI.c: -------------------------------------------------------------------------------- 1 | /* see 2 | http://wiki.scipy.org/Cookbook/C_Extensions/NumPy_arrays and 3 | http://scipy-lectures.github.io/advanced/interfacing_with_c/interfacing_with_c.html 4 | */ 5 | 6 | #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION 7 | 8 | #include 9 | #include 10 | 11 | 12 | /* a static function in C limits its scope to this file -- the linker 13 | won't complain about clashes */ 14 | static PyObject* CAPI_update(PyObject* self, PyObject* args) 15 | { 16 | 17 | PyArrayObject *iarray; 18 | double **iA; 19 | int i, j, m, n; 20 | double dx2, dy2; 21 | 22 | /* parse the inputs -- we need to know what the arguments of our 23 | call were. We'll assume: 24 | 25 | ex_function(array, dx2, dy2) 26 | 27 | and array is updated in place 28 | */ 29 | 30 | if (!PyArg_ParseTuple(args, "O!dd", 31 | &PyArray_Type, &iarray, &dx2, &dy2)) return NULL; 32 | if (NULL == iarray) return NULL; 33 | 34 | /* check to make sure we are a double type */ 35 | if (PyArray_DTYPE(iarray)->type_num != NPY_DOUBLE || 36 | PyArray_NDIM(iarray) != 2) { 37 | PyErr_SetString(PyExc_ValueError, "wrong input array type"); 38 | return NULL; 39 | } 40 | 41 | /* get the dimensions */ 42 | n = PyArray_DIM(iarray, 0); 43 | m = PyArray_DIM(iarray, 1); 44 | 45 | /* change contigous arrays into C ** arrays -- we need to have a 46 | vector of pointers that point to the correct location in the 47 | contiguous block of memory that stores the multi-dimensional 48 | array data */ 49 | iA = (double **) malloc( (size_t) (n*sizeof(double))); 50 | for (i = 0; i < n; i++) { 51 | iA[i] = (double *) PyArray_DATA(iarray) + i*m; 52 | } 53 | 54 | /* now we can do our manipulation */ 55 | for (i = 1; i < n-1; i++) { 56 | for (j = 1; j < m-1; j++) { 57 | iA[i][j] = ( (iA[i+1][j] + iA[i-1][j])*dy2 + 58 | (iA[i][j+1] + iA[i][j-1])*dx2 ) / 59 | (2.0*(dx2 + dy2)); 60 | } 61 | } 62 | 63 | 64 | /* free up the memory we allocated for the array indexing */ 65 | free (iA); 66 | 67 | /* even though we are returning an integer, it is a Python object */ 68 | return Py_BuildValue("d", 0); 69 | 70 | } 71 | 72 | 73 | /* this is the table for function names that Python will see */ 74 | static PyMethodDef laplace_CAPIMethods[] = { 75 | {"CAPI_update", CAPI_update, METH_VARARGS, "Laplace G-S update in pure C"}, 76 | {NULL, NULL, 0, NULL} 77 | }; 78 | 79 | static struct PyModuleDef moduledef = { 80 | PyModuleDef_HEAD_INIT, 81 | "laplace_CAPI", // name 82 | "a simple example: square the elements of an array", // documentation 83 | -1, // size 84 | laplace_CAPIMethods, // methods 85 | }; 86 | 87 | /* this tells python what to do when it first imports this module -- 88 | the name follows directly from the table name above */ 89 | PyMODINIT_FUNC PyInit_laplace_CAPI(void) { 90 | PyObject *m; 91 | m = PyModule_Create(&moduledef); 92 | import_array(); 93 | return m; 94 | } 95 | -------------------------------------------------------------------------------- /examples/extensions-old/timing/laplace_cython.pyx: -------------------------------------------------------------------------------- 1 | #cython: boundscheck=False 2 | #cython: wraparound=False 3 | 4 | cimport numpy as np 5 | 6 | def cy_update(np.ndarray[double, ndim=2] u, double dx2, double dy2): 7 | cdef unsigned int i, j 8 | for i in xrange(1,u.shape[0]-1): 9 | for j in xrange(1, u.shape[1]-1): 10 | u[i,j] = ((u[i+1, j] + u[i-1, j]) * dy2 + 11 | (u[i, j+1] + u[i, j-1]) * dx2) / (2*(dx2+dy2)) 12 | -------------------------------------------------------------------------------- /examples/extensions-old/timing/laplace_fortran.f90: -------------------------------------------------------------------------------- 1 | subroutine f90_update(u, nx, ny, dx2, dy2) 2 | 3 | implicit none 4 | 5 | integer, intent(in) :: nx, ny 6 | double precision, intent(inout) :: u(nx, ny) 7 | double precision, intent(in) :: dx2, dy2 8 | 9 | !f2py depend(nx, ny) :: u 10 | !f2py intent(inout) :: u 11 | !f2py intent(in) :: dx2, dy2 12 | 13 | integer :: i, j 14 | 15 | do j = 2, ny-1 16 | do i = 2, nx-1 17 | u(i,j) = ( (u(i+1,j) + u(i-1,j))*dy2 + (u(i,j+1) + u(i,j-1))*dx2 ) / & 18 | (2.0d0*(dx2 + dy2)) 19 | enddo 20 | enddo 21 | 22 | end subroutine f90_update 23 | -------------------------------------------------------------------------------- /examples/extensions-old/timing/setup.py: -------------------------------------------------------------------------------- 1 | from distutils.core import setup, Extension 2 | import numpy 3 | 4 | # define the extension module 5 | laplace_CAPI = Extension('laplace_CAPI', sources=['laplace_CAPI.c'], 6 | include_dirs=[numpy.get_include()]) #, 7 | # define_macros=[("NPY_NO_DEPRECATED_API", "NPY_1_7_API_VERSION")]) 8 | 9 | # run the setup 10 | setup(ext_modules=[laplace_CAPI]) 11 | 12 | -------------------------------------------------------------------------------- /examples/extensions/cython/README: -------------------------------------------------------------------------------- 1 | build via: 2 | 3 | python setup.py build_ext --inplace 4 | -------------------------------------------------------------------------------- /examples/extensions/cython/mandel.pyx: -------------------------------------------------------------------------------- 1 | import cython 2 | import numpy as np 3 | cimport numpy as np 4 | 5 | @cython.boundscheck(False) 6 | @cython.wraparound(False) 7 | @cython.returns(np.ndarray) 8 | def mandelbrot(int N, 9 | double xmin=-2.0, double xmax=2.0, 10 | double ymin=-2.0, double ymax=2.0, 11 | int max_iter=10): 12 | 13 | cdef np.ndarray[np.float64_t, ndim=1] x = np.linspace(xmin, xmax, N, dtype=np.float64) 14 | cdef np.ndarray[np.float64_t, ndim=1] y = np.linspace(ymin, ymax, N, dtype=np.float64) 15 | 16 | cdef np.ndarray[np.complex128_t, ndim=2] c = np.zeros((N, N), dtype=np.complex128) 17 | 18 | cdef unsigned int i, j 19 | for i in range(N): 20 | for j in range(N): 21 | c[i, j] = x[i] + 1j * y[j] 22 | 23 | cdef np.ndarray[np.complex128_t, ndim=2] z = np.zeros((N, N), dtype=np.complex128) 24 | 25 | cdef np.ndarray[np.int32_t, ndim=2] m = np.zeros((N, N), dtype=np.int32) 26 | 27 | cdef unsigned int n 28 | for n in range(1, max_iter+1): 29 | 30 | for i in range(N): 31 | for j in range(N): 32 | if m[i, j] == 0: 33 | z[i, j] = z[i, j] * z[i, j] + c[i, j] 34 | 35 | if abs(z[i,j]) > 2: 36 | m[i, j] = n 37 | 38 | return m 39 | -------------------------------------------------------------------------------- /examples/extensions/cython/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | from Cython.Build import cythonize 3 | 4 | setup(name="mandel", 5 | ext_modules=cythonize("mandel.pyx"), 6 | zip_safe=False) 7 | -------------------------------------------------------------------------------- /examples/extensions/cython/test_mandel.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | import numpy as np 3 | 4 | import mandel 5 | 6 | import time 7 | 8 | start = time.time() 9 | 10 | xmin = -2.5 11 | xmax = 1.5 12 | ymin = -2.0 13 | ymax = 2.0 14 | 15 | m = mandel.mandelbrot(1024, xmin, xmax, ymin, ymax, max_iter=50) 16 | 17 | print(f"execution time = {time.time() - start}\n") 18 | 19 | fig, ax = plt.subplots() 20 | ax.imshow(np.transpose(m % 16), origin="lower", 21 | extent=[xmin, xmax, ymin, ymax], cmap="viridis") 22 | 23 | fig.tight_layout() 24 | fig.savefig("test.png") 25 | -------------------------------------------------------------------------------- /examples/extensions/f2py/README: -------------------------------------------------------------------------------- 1 | Note: python >= 3.12 needs ninja and meson to build. 2 | 3 | Build this as: 4 | 5 | f2py -c mandel.f90 -m mandel_f2py 6 | 7 | then you can `import mandel_f2py` in python. 8 | -------------------------------------------------------------------------------- /examples/extensions/f2py/mandel.f90: -------------------------------------------------------------------------------- 1 | subroutine mandelbrot(N, xmin, xmax, ymin, ymax, max_iter, m) 2 | 3 | implicit none 4 | 5 | integer, intent(in) :: N 6 | double precision, intent(in) :: xmin, xmax, ymin, ymax 7 | integer, intent(in) :: max_iter 8 | 9 | integer, intent(out) :: m(N, N) 10 | 11 | double complex, parameter :: i_unit = (0, 1) 12 | 13 | !f2py depend(N) :: m 14 | !f2py intent(out) :: m 15 | 16 | integer :: i, j, niter 17 | double precision :: x(N), y(N) 18 | double precision :: dx, dy 19 | double complex, allocatable :: c(:, :) 20 | double complex, allocatable :: z(:, :) 21 | 22 | ! compute coordinates 23 | dx = (xmax - xmin) / (N - 1) 24 | dy = (ymax - ymin) / (N - 1) 25 | 26 | do i = 1, N 27 | x(i) = xmin + (i-1) * dx 28 | y(i) = ymin + (i-1) * dy 29 | enddo 30 | 31 | allocate(c(N, N)) 32 | 33 | do j = 1, N 34 | do i = 1, N 35 | c(i, j) = x(i) + i_unit * y(j) 36 | enddo 37 | enddo 38 | 39 | m(:, :) = 0 40 | 41 | allocate(z(N, N)) 42 | z(:, :) = 0.0 43 | 44 | do niter = 1, max_iter 45 | 46 | do j = 1, N 47 | do i = 1, N 48 | 49 | if (m(i, j) == 0) then 50 | z(i, j) = z(i, j) * z(i, j) + c(i, j) 51 | 52 | if (abs(z(i,j)) > 2) then 53 | m(i, j) = niter 54 | endif 55 | endif 56 | 57 | enddo 58 | enddo 59 | 60 | enddo 61 | 62 | end subroutine mandelbrot 63 | -------------------------------------------------------------------------------- /examples/extensions/f2py/test_mandel.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | import numpy as np 3 | 4 | import mandel_f2py 5 | 6 | import time 7 | 8 | start = time.time() 9 | 10 | xmin = -2.5 11 | xmax = 1.5 12 | ymin = -2.0 13 | ymax = 2.0 14 | 15 | max_iter = 50 16 | 17 | m = mandel_f2py.mandelbrot(1024, xmin, xmax, ymin, ymax, max_iter) 18 | 19 | print(f"execution time = {time.time() - start}\n") 20 | 21 | fig, ax = plt.subplots() 22 | ax.imshow(np.transpose(m), origin="lower", 23 | extent=[xmin, xmax, ymin, ymax]) 24 | 25 | fig.tight_layout() 26 | fig.savefig("test.png") 27 | -------------------------------------------------------------------------------- /examples/extensions/numba/mandel.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from numba import njit 4 | 5 | 6 | @njit(nopython=True) 7 | def mandelbrot(N, 8 | xmin=-2.0, xmax=2.0, 9 | ymin=-2.0, ymax=2.0, 10 | max_iter=10): 11 | 12 | x = np.linspace(xmin, xmax, N) 13 | y = np.linspace(ymin, ymax, N) 14 | 15 | c = np.zeros((N, N), dtype=np.complex128) 16 | 17 | for i in range(N): 18 | for j in range(N): 19 | c[i, j] = x[i] + 1j * y[j] 20 | 21 | z = np.zeros((N, N), dtype=np.complex128) 22 | 23 | # note: we need to use a numba type here 24 | m = np.zeros((N, N), dtype=np.int32) 25 | 26 | for n in range(1, max_iter+1): 27 | 28 | for i in range(N): 29 | for j in range(N): 30 | if m[i, j] == 0: 31 | z[i, j] = z[i, j] * z[i, j] + c[i, j] 32 | 33 | if np.abs(z[i, j]) > 2: 34 | m[i, j] = n 35 | 36 | return m 37 | -------------------------------------------------------------------------------- /examples/extensions/numba/test_mandel.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | import numpy as np 3 | 4 | import mandel 5 | 6 | import time 7 | 8 | start = time.time() 9 | 10 | xmin = -2.5 11 | xmax = 1.5 12 | ymin = -2.0 13 | ymax = 2.0 14 | 15 | m = mandel.mandelbrot(1024, xmin, xmax, ymin, ymax, max_iter=50) 16 | 17 | print(f"execution time (including jit) = {time.time() - start}\n") 18 | 19 | start = time.time() 20 | 21 | m = mandel.mandelbrot(1024, xmin, xmax, ymin, ymax, max_iter=50) 22 | 23 | print(f"second run time = {time.time() - start}\n") 24 | 25 | fig, ax = plt.subplots() 26 | ax.imshow(np.transpose(m % 16), origin="lower", 27 | extent=[xmin, xmax, ymin, ymax], cmap="viridis") 28 | 29 | fig.tight_layout() 30 | fig.savefig("test.png") 31 | -------------------------------------------------------------------------------- /examples/extensions/pybind11/README: -------------------------------------------------------------------------------- 1 | 2 | pip install pybind11 3 | 4 | g++ -O3 -Wall -Wextra -shared -std=c++17 -fPIC $(python3 -m pybind11 --includes) mandel.cpp -o mandel$(python3-config --extension-suffix) 5 | 6 | 7 | see https://stackoverflow.com/questions/44659924/returning-numpy-arrays-via-pybind11 8 | for how to construct the array we are going to return in the subroutine itself. 9 | 10 | -------------------------------------------------------------------------------- /examples/extensions/pybind11/contiguous/README: -------------------------------------------------------------------------------- 1 | This version uses a simple Array class to give us nice indexing into a contiguous array 2 | 3 | pip install pybind11 4 | 5 | g++ -DNDEBUG -O3 -Wall -Wextra -shared -std=c++17 -fPIC $(python3 -m pybind11 --includes) mandel.cpp -o mandel$(python3-config --extension-suffix) 6 | 7 | 8 | see https://stackoverflow.com/questions/44659924/returning-numpy-arrays-via-pybind11 9 | for how to construct the array we are going to return in the subroutine itself. 10 | 11 | -------------------------------------------------------------------------------- /examples/extensions/pybind11/contiguous/mandel.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | 9 | namespace py = pybind11; 10 | 11 | using namespace std::complex_literals; 12 | 13 | class Array { 14 | 15 | int N; 16 | std::vector> _data; 17 | 18 | public: 19 | 20 | Array(int N_in) 21 | : N(N_in), _data(N_in * N_in, 0.0) {} 22 | 23 | inline std::complex& operator() (int row, int col) { 24 | return _data[row * N + col]; 25 | } 26 | }; 27 | 28 | py::array_t mandelbrot(int N, 29 | double xmin, double xmax, 30 | double ymin, double ymax, int max_iter) { 31 | 32 | // construct the numpy array we will return 33 | // we need to specify the strides manually 34 | 35 | constexpr std::size_t elsize = sizeof(int); 36 | std::size_t shape[2]{N, N}; 37 | std::size_t strides[2]{N * elsize, elsize}; 38 | auto m = py::array_t(shape, strides); 39 | auto m_view = m.mutable_unchecked<2>(); 40 | 41 | // we'll use a simple contiguous array here. When 42 | // C++23 mdspan is available, that will be preferred. 43 | 44 | std::vector x(N, 0.0); 45 | std::vector y(N, 0.0); 46 | 47 | double dx = (xmax - xmin) / static_cast(N - 1); 48 | double dy = (ymax - ymin) / static_cast(N - 1); 49 | 50 | for (int i = 0; i < N; ++i) { 51 | x[i] = xmin + static_cast(i) * dx; 52 | y[i] = ymin + static_cast(i) * dy; 53 | } 54 | 55 | Array c(N); 56 | Array z(N); 57 | 58 | // initialize c; 59 | 60 | for (int i = 0; i < N; ++i) { 61 | for (int j = 0; j < N; ++j) { 62 | c(i, j) = x[i] + 1i * y[j]; 63 | } 64 | } 65 | 66 | // zero out the output array 67 | 68 | for (int i = 0; i < m.shape(0); ++i) { 69 | for (int j = 0; j < m.shape(1); ++j) { 70 | m_view(i, j) = 0; 71 | } 72 | } 73 | 74 | for (int niter = 1; niter <= max_iter; ++niter) { 75 | 76 | for (int i = 0; i < m.shape(0); ++i) { 77 | for (int j = 0; j < m.shape(1); ++j) { 78 | 79 | if (m_view(i, j) == 0) { 80 | z(i, j) = z(i, j) * z(i, j) + c(i, j); 81 | 82 | if (std::abs(z(i, j)) > 2) { 83 | m_view(i, j) = niter; 84 | } 85 | } 86 | } 87 | } 88 | } 89 | 90 | return m; 91 | } 92 | 93 | 94 | PYBIND11_MODULE(mandel, m) { 95 | m.doc() = "C++ Mandelbrot example"; 96 | m.def("mandelbrot", &mandelbrot, "generate the Mandelbrot set of size N"); 97 | } 98 | -------------------------------------------------------------------------------- /examples/extensions/pybind11/contiguous/test_mandel.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | import numpy as np 3 | 4 | import mandel 5 | 6 | import time 7 | 8 | start = time.time() 9 | 10 | xmin = -2.5 11 | xmax = 1.5 12 | ymin = -2.0 13 | ymax = 2.0 14 | 15 | max_iter = 50 16 | 17 | m = mandel.mandelbrot(1024, xmin, xmax, ymin, ymax, max_iter) 18 | 19 | print(f"execution time = {time.time() - start}\n") 20 | 21 | 22 | fig, ax = plt.subplots() 23 | ax.imshow(np.transpose(m), origin="lower", 24 | extent=[xmin, xmax, ymin, ymax]) 25 | 26 | fig.tight_layout() 27 | fig.savefig("test.png") 28 | -------------------------------------------------------------------------------- /examples/extensions/pybind11/mandel.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | 10 | namespace py = pybind11; 11 | 12 | using cmplx_arr = std::vector>>; 13 | 14 | using namespace std::complex_literals; 15 | 16 | 17 | py::array_t mandelbrot(int N, 18 | double xmin, double xmax, 19 | double ymin, double ymax, int max_iter) { 20 | 21 | // construct the numpy array we will return 22 | // we need to specify the strides manually 23 | 24 | constexpr std::size_t elsize = sizeof(int); 25 | std::size_t shape[2]{N, N}; 26 | std::size_t strides[2]{N * elsize, elsize}; 27 | auto m = py::array_t(shape, strides); 28 | auto m_view = m.mutable_unchecked<2>(); 29 | 30 | // for the other arrays used only here, we can 31 | // do whatever we want. Since we can't yet rely 32 | // on C++23 mdspan, we'll just do a vector of vectors 33 | 34 | std::vector x(N, 0.0); 35 | std::vector y(N, 0.0); 36 | 37 | double dx = (xmax - xmin) / static_cast(N - 1); 38 | double dy = (ymax - ymin) / static_cast(N - 1); 39 | 40 | for (int i = 0; i < N; ++i) { 41 | x[i] = xmin + static_cast(i) * dx; 42 | y[i] = ymin + static_cast(i) * dy; 43 | } 44 | 45 | cmplx_arr c(N, std::vector>(N, 0.0)); 46 | cmplx_arr z(N, std::vector>(N, 0.0)); 47 | 48 | // initialize c; 49 | 50 | for (int i = 0; i < N; ++i) { 51 | for (int j = 0; j < N; ++j) { 52 | c[i][j] = x[i] + 1i * y[j]; 53 | } 54 | } 55 | 56 | // zero out the output array 57 | 58 | for (int i = 0; i < m.shape(0); ++i) { 59 | for (int j = 0; j < m.shape(1); ++j) { 60 | m_view(i, j) = 0; 61 | } 62 | } 63 | 64 | for (int niter = 1; niter <= max_iter; ++niter) { 65 | 66 | for (int i = 0; i < m.shape(0); ++i) { 67 | for (int j = 0; j < m.shape(1); ++j) { 68 | 69 | if (m_view(i, j) == 0) { 70 | z[i][j] = z[i][j] * z[i][j] + c[i][j]; 71 | 72 | if (std::abs(z[i][j]) > 2) { 73 | m_view(i, j) = niter; 74 | } 75 | } 76 | } 77 | } 78 | } 79 | 80 | return m; 81 | } 82 | 83 | 84 | PYBIND11_MODULE(mandel, m) { 85 | m.doc() = "C++ Mandelbrot example"; 86 | m.def("mandelbrot", &mandelbrot, "generate the Mandelbrot set of size N"); 87 | } 88 | -------------------------------------------------------------------------------- /examples/extensions/pybind11/test_mandel.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | import numpy as np 3 | 4 | import mandel 5 | 6 | import time 7 | 8 | start = time.time() 9 | 10 | xmin = -2.5 11 | xmax = 1.5 12 | ymin = -2.0 13 | ymax = 2.0 14 | 15 | max_iter = 50 16 | 17 | m = mandel.mandelbrot(1024, xmin, xmax, ymin, ymax, max_iter) 18 | 19 | print(f"execution time = {time.time() - start}\n") 20 | 21 | 22 | fig, ax = plt.subplots() 23 | ax.imshow(np.transpose(m), origin="lower", 24 | extent=[xmin, xmax, ymin, ymax]) 25 | 26 | fig.tight_layout() 27 | fig.savefig("test.png") 28 | -------------------------------------------------------------------------------- /examples/extensions/python-slow/mandel.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | def mandelbrot(N, 4 | xmin=-2.0, xmax=2.0, 5 | ymin=-2.0, ymax=2.0, 6 | max_iter=10): 7 | 8 | x = np.linspace(xmin, xmax, N) 9 | y = np.linspace(ymin, ymax, N) 10 | 11 | c = np.zeros((N, N), dtype=np.complex128) 12 | 13 | for i in range(N): 14 | for j in range(N): 15 | c[i, j] = x[i] + 1j * y[j] 16 | 17 | z = np.zeros((N, N), dtype=np.complex128) 18 | 19 | # note: we need to use a numba type here 20 | m = np.zeros((N, N), dtype=np.int32) 21 | 22 | for n in range(1, max_iter+1): 23 | 24 | for i in range(N): 25 | for j in range(N): 26 | if m[i, j] == 0: 27 | z[i, j] = z[i, j] * z[i, j] + c[i, j] 28 | 29 | if np.abs(z[i,j]) > 2: 30 | m[i, j] = n 31 | 32 | return m 33 | -------------------------------------------------------------------------------- /examples/extensions/python-slow/test_mandel.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | import numpy as np 3 | 4 | import mandel 5 | 6 | import time 7 | 8 | start = time.time() 9 | 10 | xmin = -2.5 11 | xmax = 1.5 12 | ymin = -2.0 13 | ymax = 2.0 14 | 15 | m = mandel.mandelbrot(1024, xmin, xmax, ymin, ymax, max_iter=50) 16 | 17 | print(f"execution time = {time.time() - start}\n") 18 | 19 | fig, ax = plt.subplots() 20 | ax.imshow(np.transpose(m % 16), origin="lower", 21 | extent=[xmin, xmax, ymin, ymax], cmap="viridis") 22 | 23 | fig.tight_layout() 24 | fig.savefig("test.png") 25 | -------------------------------------------------------------------------------- /examples/extensions/python/mandel.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | def mandelbrot(N, 4 | xmin=-2.0, xmax=2.0, 5 | ymin=-2.0, ymax=2.0, 6 | max_iter=10): 7 | 8 | x = np.linspace(xmin, xmax, N) 9 | y = np.linspace(ymin, ymax, N) 10 | 11 | xv, yv = np.meshgrid(x, y, indexing="ij") 12 | 13 | c = xv + 1j*y 14 | 15 | z = np.zeros((N, N), dtype=np.complex128) 16 | 17 | m = np.zeros((N, N), dtype=np.int32) 18 | 19 | for i in range(1, max_iter+1): 20 | z[m == 0] = z[m == 0]**2 + c[m == 0] 21 | 22 | m[np.logical_and(np.abs(z) > 2, m == 0)] = i 23 | 24 | return m 25 | -------------------------------------------------------------------------------- /examples/extensions/python/test_mandel.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | import numpy as np 3 | 4 | import mandel 5 | 6 | import time 7 | 8 | start = time.time() 9 | 10 | xmin = -2.5 11 | xmax = 1.5 12 | ymin = -2.0 13 | ymax = 2.0 14 | 15 | m = mandel.mandelbrot(1024, xmin, xmax, ymin, ymax, max_iter=50) 16 | 17 | print(f"execution time = {time.time() - start}\n") 18 | 19 | fig, ax = plt.subplots() 20 | ax.imshow(np.transpose(m % 16), origin="lower", 21 | extent=[xmin, xmax, ymin, ymax], cmap="viridis") 22 | 23 | fig.tight_layout() 24 | fig.savefig("test.png") 25 | -------------------------------------------------------------------------------- /examples/external/Popen/githash.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import string 3 | 4 | # issue the command 'git rev-parse HEAD' 5 | prog = ["git", "rev-parser", "HEAD"] 6 | p0 = subprocess.Popen(prog, stdout=subprocess.PIPE, 7 | stderr=subprocess.PIPE) 8 | stdout0, stderr0 = p0.communicate() 9 | 10 | print "stdout: {}".format(stdout0) 11 | print "stderr: {}".format(stderr0) 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/h5py/h5_example.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import h5py 3 | 4 | 5 | a = np.arange(1000, dtype=np.float64).reshape(25, 40) 6 | 7 | with h5py.File("test.h5", "w") as f: 8 | 9 | # attributes are meta-data that can help describe the data 10 | # in h5py, they are dictionary keys 11 | f.attrs["about"] = "a test HDF5 file with h5py" 12 | 13 | # groups can be thought of as subdirectories in the output file, 14 | # and can help you organize data together logically 15 | grp = f.create_group("data") 16 | 17 | # a numpy array is a dataset in HDF5 -- it will figure out the 18 | # dimensions and type from the array itself 19 | grp.create_dataset("a", data=a) 20 | 21 | # there can be attributes in the group too 22 | grp.attrs["array info"] = "a simple array" 23 | 24 | 25 | # now we'll try to read it in 26 | with h5py.File("test.h5", "r") as f: 27 | 28 | # access the group we stored our data in 29 | g = f["data"] 30 | 31 | aread = np.array(g["a"]) 32 | 33 | 34 | # are they the same? 35 | da = a - aread 36 | print(np.max(abs(da))) 37 | -------------------------------------------------------------------------------- /examples/linear-algebra/gaussian-elimination/gauss-test.py: -------------------------------------------------------------------------------- 1 | import numpy 2 | from gauss import * 3 | from matmul import * 4 | 5 | # tests of gaussian elimination 6 | 7 | A = numpy.array([ [1, 1, 1], [-1, 2, 0], [2, 0, 1] ], dtype=numpy.float64) 8 | b = numpy.array([6, 3, 5], dtype=numpy.float64) 9 | # gaussElim changes A in place -- send a copy 10 | x, d = gaussElim(A.copy(), b.copy(), returnDet=1) 11 | 12 | # test it by multiplying A x 13 | bout = mult_Ax(A, x) 14 | 15 | print "matrix A:\n", A 16 | print "RHS (b): ", b 17 | print "solved x: ", x 18 | print "det{A}: ", d 19 | print "A.x: ", bout 20 | print " " 21 | 22 | A = numpy.array([ [0, 1, 1], [1, 1, 0], [1, 0, 1] ], dtype=numpy.float64) 23 | b = numpy.array([5, 3, 4], dtype=numpy.float64) 24 | x = gaussElim(A.copy(), b.copy()) 25 | 26 | # test it by multiplying A x 27 | bout = mult_Ax(A, x) 28 | 29 | print "matrix A:\n", A 30 | print "RHS (b): ", b 31 | print "solved x: ", x 32 | print "A.x: ", bout 33 | print " " 34 | 35 | 36 | A = numpy.array([ [0, 0, 0, 4], 37 | [0, 0, 3, 0], 38 | [5, 6, 7, 8], 39 | [0, 4, 3, 2] ], dtype=numpy.float64) 40 | b = numpy.array([5, 4, 9, 1], dtype=numpy.float64) 41 | x = gaussElim(A.copy(), b.copy()) 42 | 43 | # test it by multiplying A x 44 | bout = mult_Ax(A, x) 45 | 46 | print "matrix A:\n", A 47 | print "RHS (b): ", b 48 | print "solved x: ", x 49 | print "A.x: ", bout 50 | print " " 51 | 52 | 53 | A = numpy.array([ [ 4, 3, 4, 10], 54 | [ 2, -7, 3, 0], 55 | [-2, 11, 1, 3], 56 | [ 3, -4, 0, 2] ], dtype=numpy.float64) 57 | b = numpy.array([2, 6, 3, 1], dtype=numpy.float64) 58 | x = gaussElim(A.copy(), b.copy()) 59 | 60 | # test it by multiplying A x 61 | bout = mult_Ax(A, x) 62 | 63 | print "matrix A:\n", A 64 | print "RHS (b): ", b 65 | print "solved x: ", x 66 | print "A.x: ", bout 67 | print " " 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /examples/linear-algebra/gaussian-elimination/matmul.py: -------------------------------------------------------------------------------- 1 | # routines for multiplying matrices 2 | import numpy 3 | 4 | def mult_Ax(A, x): 5 | """ return the product of matrix A and vector x: Ax = b """ 6 | 7 | # x is a vector 8 | if not x.ndim == 1: 9 | print "ERROR: x should be a vector" 10 | return None 11 | 12 | N = len(x) 13 | 14 | # A is square, with each dimension of length N 15 | if not (A.shape[0] == N and A.shape[1] == N): 16 | print "ERROR: A should be square with each dim of same length as x" 17 | return None 18 | 19 | # allocation the product array 20 | b = numpy.zeros((N), dtype=A.dtype) 21 | 22 | # each row of b is the product of the like row of A dotted with 23 | # the vector x 24 | for i in range(N): 25 | b[i] = numpy.dot(A[i,:], x) 26 | 27 | return b 28 | 29 | -------------------------------------------------------------------------------- /examples/linear-algebra/tridiagonal/lap.py: -------------------------------------------------------------------------------- 1 | # we want to solve f" = g(x) 2 | # 3 | # differencing f_{i+1} - 2 f_i + f_{i-1} = dx**2 g_i 4 | # 5 | # imagine that our grid runs from 0, ... N-1. We specify Dirichlet 6 | # boundary conditions at 0 and N-1, so we only need to solve for 7 | # the interior points, 1, ..., N-2. 8 | # 9 | # at the left boundary, we have: 10 | # 11 | # f_2 - 2 f_1 = dx**2 g_1 12 | # 13 | # at the right boundary, we have: 14 | # 15 | # -2 f_{N-1} + f_{N-2} = dx**2 g_{N-1} 16 | # 17 | # Our system can be written as: 18 | # 19 | # A f = dx**2 g 20 | # 21 | # where A is an (N-2) x (N-2) tridiagonal matrix and f is the solution 22 | # for the N-2 interior points. 23 | # 24 | # Here, we'll solve f" = sin x on [0, 2pi], with f(0) = f(2pi) = 0. This 25 | # has the analytic solution f(x) = -sin x 26 | 27 | import numpy as np 28 | from scipy import linalg 29 | import pylab 30 | 31 | 32 | # our grid -- including endpoints 33 | N = 100 34 | x = np.linspace(0.0, 2.0*np.pi, N, endpoint=True) 35 | dx = x[1]-x[0] 36 | 37 | # our source 38 | g = np.sin(x) 39 | 40 | # our matrix will be tridiagonal, with [1, -2, 1] on the diagonals 41 | # we only solve for the N-2 interior points 42 | 43 | # diagonal 44 | d = -2*np.ones(N-2) 45 | 46 | # upper -- note that the upper diagonal has 1 less element than the 47 | # main diagonal. The SciPy banded solver wants the matrix in the 48 | # form: 49 | # 50 | # * a01 a12 a23 a34 a45 <- upper diagonal 51 | # a00 a11 a22 a33 a44 a55 <- diagonal 52 | # a10 a21 a32 a43 a54 * <- lower diagonal 53 | # 54 | 55 | u = np.ones(N-2) 56 | u[0] = 0.0 57 | 58 | # lower 59 | l = np.ones(N-2) 60 | l[N-3] = 0.0 61 | 62 | # put the upper, diagonal, and lower parts together as a banded matrix 63 | A = np.matrix([u,d,l]) 64 | 65 | # solve A sol = dx**2 g for the inner N-2 points 66 | sol = linalg.solve_banded((1,1), A, dx**2*g[1:N-1]) 67 | 68 | pylab.plot(x[1:N-1], sol) 69 | pylab.savefig("lap.png") 70 | 71 | -------------------------------------------------------------------------------- /examples/machine-learning/character_recognition/README: -------------------------------------------------------------------------------- 1 | This example is inspired from "Make your own Neural Network" by Tariq 2 | Rashid, using the notation from Franklin. 3 | 4 | Some diffs w/ Franklin: 5 | 6 | -- we use back-propagation to get the errors at on the hidden layer 7 | 8 | -- we set alpha = 1 -- the intent is that you come in with x in [0, 1] 9 | 10 | -- we initialize the matricies with Gaussian normal random numbers 11 | with a width mu = 1/sqrt(n), where n is the size of the input 12 | vector. 13 | 14 | -- we don't offset the output from the hidden layer to shift it into 15 | [-0.5, 0.5] 16 | 17 | -------------------------------------------------------------------------------- /examples/machine-learning/character_recognition/nn_epochs.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | import char_recognition as cr 3 | 4 | epoch = [] 5 | fraction = [] 6 | 7 | for e in range(1, 10): 8 | f = cr.main(do_plots=False, n_epochs=e) 9 | epoch.append(e) 10 | fraction.append(f) 11 | 12 | plt.plot(epoch, fraction) 13 | plt.xlabel("number of training epochs") 14 | plt.ylabel("success fraction") 15 | plt.tight_layout() 16 | plt.savefig("epoch_trends.png", dpi=150) 17 | 18 | for e, f in zip(epoch, fraction): 19 | print(e, f) 20 | -------------------------------------------------------------------------------- /examples/machine-learning/character_recognition/nn_hidden_size.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | import char_recognition as cr 3 | 4 | fraction = [] 5 | 6 | hidden_sizes = [25, 50, 100, 200, 400] 7 | for h in hidden_sizes: 8 | f = cr.main(do_plots=False, hidden_layer_size=h) 9 | fraction.append(f) 10 | 11 | 12 | plt.plot(hidden_sizes, fraction) 13 | plt.xlabel("hidden layer size") 14 | plt.ylabel("success fraction") 15 | plt.tight_layout() 16 | plt.savefig("hidden_layer_trends.png", dpi=150) 17 | 18 | for h, e in zip(hidden_sizes, fraction): 19 | print(h, e) 20 | -------------------------------------------------------------------------------- /examples/machine-learning/character_recognition/nn_learning_rate.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | import char_recognition as cr 3 | 4 | fraction = [] 5 | 6 | learning_rate = [0.05, 0.1, 0.2, 0.3, 0.4] 7 | for l in learning_rate: 8 | f = cr.main(do_plots=False, learning_rate=l) 9 | fraction.append(f) 10 | 11 | 12 | plt.plot(learning_rate, fraction) 13 | plt.xlabel("learning rate") 14 | plt.ylabel("success fraction") 15 | plt.tight_layout() 16 | plt.savefig("learning_rate_trends.png", dpi=150) 17 | 18 | for l, e in zip(learning_rate, fraction): 19 | print(l, e) 20 | -------------------------------------------------------------------------------- /examples/machine-learning/character_recognition/nn_training_size.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | import char_recognition as cr 3 | 4 | fraction = [] 5 | 6 | training_size = [1875, 3750, 7500, 15000, 30000, 60000] 7 | for t in training_size: 8 | f = cr.main(do_plots=False, num_training_unique=t) 9 | fraction.append(f) 10 | 11 | 12 | plt.plot(training_size, fraction) 13 | plt.xlabel("training sample size") 14 | plt.ylabel("success fraction") 15 | plt.tight_layout() 16 | plt.savefig("training_size_trends.png", dpi=150) 17 | 18 | for h, e in zip(training_size, fraction): 19 | print(h, e) 20 | -------------------------------------------------------------------------------- /examples/machine-learning/character_recognition/show_character.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | import char_recognition as cr 3 | 4 | train_set = cr.TrainingSet() 5 | 6 | d = train_set.get_next() 7 | d.plot() 8 | plt.tight_layout() 9 | plt.savefig("example_digit.png", bbox_inches="tight", dpi=150) 10 | -------------------------------------------------------------------------------- /examples/machine-learning/keras/feed-forward/README.md: -------------------------------------------------------------------------------- 1 | These examples come from: 2 | 3 | https://github.com/Vict0rSch/deep_learning/tree/master/keras/feedforward 4 | -------------------------------------------------------------------------------- /examples/machine-learning/keras/feed-forward/feedforward_keras_mnist.py: -------------------------------------------------------------------------------- 1 | import time 2 | import numpy as np 3 | from matplotlib import pyplot as plt 4 | from keras.utils import np_utils 5 | import keras.callbacks as cb 6 | from keras.models import Sequential 7 | from keras.layers.core import Dense, Dropout, Activation 8 | from keras.optimizers import RMSprop 9 | from keras.datasets import mnist 10 | 11 | 12 | class LossHistory(cb.Callback): 13 | def on_train_begin(self, logs={}): 14 | self.losses = [] 15 | 16 | def on_batch_end(self, batch, logs={}): 17 | batch_loss = logs.get('loss') 18 | self.losses.append(batch_loss) 19 | 20 | 21 | def load_data(): 22 | print 'Loading data...' 23 | (X_train, y_train), (X_test, y_test) = mnist.load_data() 24 | 25 | X_train = X_train.astype('float32') 26 | X_test = X_test.astype('float32') 27 | 28 | X_train /= 255 29 | X_test /= 255 30 | 31 | y_train = np_utils.to_categorical(y_train, 10) 32 | y_test = np_utils.to_categorical(y_test, 10) 33 | 34 | X_train = np.reshape(X_train, (60000, 784)) 35 | X_test = np.reshape(X_test, (10000, 784)) 36 | 37 | print 'Data loaded.' 38 | return [X_train, X_test, y_train, y_test] 39 | 40 | 41 | def init_model(): 42 | start_time = time.time() 43 | print 'Compiling Model ... ' 44 | model = Sequential() 45 | model.add(Dense(500, input_dim=784)) 46 | model.add(Activation('relu')) 47 | model.add(Dropout(0.4)) 48 | model.add(Dense(300)) 49 | model.add(Activation('relu')) 50 | model.add(Dropout(0.4)) 51 | model.add(Dense(10)) 52 | model.add(Activation('softmax')) 53 | 54 | rms = RMSprop() 55 | model.compile(loss='categorical_crossentropy', optimizer=rms, metrics=['accuracy']) 56 | print 'Model compield in {0} seconds'.format(time.time() - start_time) 57 | return model 58 | 59 | 60 | def run_network(data=None, model=None, epochs=20, batch=256): 61 | try: 62 | start_time = time.time() 63 | if data is None: 64 | X_train, X_test, y_train, y_test = load_data() 65 | else: 66 | X_train, X_test, y_train, y_test = data 67 | 68 | if model is None: 69 | model = init_model() 70 | 71 | history = LossHistory() 72 | 73 | print 'Training model...' 74 | model.fit(X_train, y_train, nb_epoch=epochs, batch_size=batch, 75 | callbacks=[history], 76 | validation_data=(X_test, y_test), verbose=2) 77 | 78 | print "Training duration : {0}".format(time.time() - start_time) 79 | score = model.evaluate(X_test, y_test, batch_size=16) 80 | 81 | print "Network's test score [loss, accuracy]: {0}".format(score) 82 | return model, history.losses 83 | except KeyboardInterrupt: 84 | print ' KeyboardInterrupt' 85 | return model, history.losses 86 | 87 | 88 | def plot_losses(losses): 89 | fig = plt.figure() 90 | ax = fig.add_subplot(111) 91 | ax.plot(losses) 92 | ax.set_title('Loss per batch') 93 | fig.show() 94 | -------------------------------------------------------------------------------- /examples/machine-learning/steepest_descent/min_2d_descent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/examples/machine-learning/steepest_descent/min_2d_descent.png -------------------------------------------------------------------------------- /examples/machine-learning/steepest_descent/min_2d_start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/examples/machine-learning/steepest_descent/min_2d_start.png -------------------------------------------------------------------------------- /examples/machine-learning/steepest_descent/steepest_descent.py: -------------------------------------------------------------------------------- 1 | # an example of steepest (gradient) descent minimization 2 | 3 | import numpy as np 4 | import matplotlib.pyplot as plt 5 | 6 | def rosenbrock(x0, x1, a, b): 7 | return (a - x0)**2 + b*(x1 - x0**2)**2 8 | 9 | def drosdx(x, a, b): 10 | x0 = x[0] 11 | x1 = x[1] 12 | return np.array([-2.0*(a - x0) - 4.0*b*(x1 - x0**2)*x0, 13 | 2.0*b*(x1 - x0**2)]) 14 | 15 | def main(): 16 | 17 | xmin = -2.0 18 | xmax = 2.0 19 | ymin = -1.0 20 | ymax = 3.0 21 | 22 | a = 1.0 23 | b = 100.0 24 | 25 | N = 256 26 | x = np.linspace(xmin, xmax, N) 27 | y = np.linspace(ymin, ymax, N) 28 | 29 | x2d, y2d = np.meshgrid(x, y, indexing="ij") 30 | 31 | plt.imshow(np.log10(np.transpose(rosenbrock(x2d, y2d, a, b))), 32 | origin="lower", 33 | extent=[xmin, xmax, ymin, ymax]) 34 | 35 | plt.colorbar() 36 | plt.tight_layout() 37 | 38 | plt.savefig("min_2d_start.png", dpi=150) 39 | 40 | 41 | # do descent 42 | xp = np.array([-1.0, 1.5]) 43 | xp_old = 1000*xp 44 | 45 | eps = 1.e-5 46 | 47 | eta = 0.002 48 | 49 | while np.linalg.norm(xp - xp_old) > eps: 50 | xp_old[:] = xp[:] 51 | grad = drosdx(xp, a, b) 52 | 53 | # eta_pred = rosenbrock(xp[0], xp[1], a, b)/np.linalg.norm(grad) 54 | # print("eta predict = ", eta_pred) 55 | xp[:] += -eta * grad[:] 56 | 57 | plt.plot([xp_old[0], xp[0]], [xp_old[1], xp[1]], color="C1") 58 | 59 | plt.scatter([xp[0]], [xp[1]], marker="o", color="C1") 60 | 61 | print(xp) 62 | 63 | plt.savefig("min_2d_descent.png", dpi=150) 64 | 65 | if __name__ == "__main__": 66 | main() 67 | -------------------------------------------------------------------------------- /examples/matplotlib/fractal/mandelbrot.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | import numpy as np 3 | 4 | # the mandelbrot set is defined such that z_{n+1} = z_n^2 + c 5 | # remains bounded, which is sufficient to say that |z_{n+1}| <= 2 6 | # where c is a complex # and we start with z_0 = 0 7 | 8 | # we want to consider a range of c, as complex numbers c = x + iy, 9 | # were -2 < x < 2 and -2 < y < 2 10 | 11 | N = 1024 12 | 13 | c = np.zeros((N, N), dtype=np.complex) 14 | 15 | region = 2 16 | 17 | if region == 0: 18 | xmin = -2 19 | xmax = 1 20 | ymin = -1.5 21 | ymax = 1.5 22 | 23 | elif region == 1: 24 | xmin = 0 25 | xmax = 0.5 26 | ymin = -0.75 27 | ymax = -0.25 28 | 29 | elif region == 2: 30 | # nice spot 31 | xc = -0.7435669 32 | yc = 0.1314023 33 | dx = 0.004 #0.0022878 34 | 35 | xmin = xc-0.5*dx 36 | xmax = xc+0.5*dx 37 | ymin = yc-0.5*dx 38 | ymax = yc+0.5*dx 39 | 40 | elif region == 3: 41 | # dagger 42 | xmin = -0.8 43 | xmax = -0.7 44 | ymin = 0.0 45 | ymax = 0.1 46 | 47 | x = np.linspace(xmin, xmax, N, dtype=np.float) 48 | y = np.linspace(ymin, ymax, N, dtype=np.float) 49 | 50 | c[:,:].real = x[:,np.newaxis] 51 | c[:,:].imag = y[np.newaxis,:] 52 | 53 | z = np.zeros((N,N), dtype=np.complex) 54 | 55 | niter = np.zeros((N,N), dtype=np.int) 56 | niter[:,:] = -1 57 | 58 | MAX_ITER = 1024 59 | 60 | for n in range(MAX_ITER): 61 | idx = niter == -1 62 | z[idx] = z[idx]**2 + c[idx] 63 | idx = np.logical_and(abs(z) > 2, niter == -1) 64 | niter[idx] = n 65 | 66 | # some things may still have not passed 67 | niter[niter == -1] = MAX_ITER-1 68 | 69 | plt.imshow(np.log10(niter.T), extent=[xmin, xmax, ymin, ymax], 70 | origin="lower", cmap="magma_r") 71 | 72 | f = plt.gcf() 73 | f.set_size_inches(8.0, 8.0) 74 | plt.savefig("mandel.png") 75 | -------------------------------------------------------------------------------- /examples/mayavi/mayavi-basic.py: -------------------------------------------------------------------------------- 1 | # http://docs.enthought.com/mayavi/mayavi/mlab_case_studies.html 2 | 3 | import numpy as np 4 | 5 | from mayavi import mlab 6 | 7 | x, y, z = np.ogrid[-10:10:20j, -10:10:20j, -10:10:20j] 8 | s = np.sin(x*y*z)/(x*y*z) 9 | 10 | mlab.contour3d(s) 11 | mlab.show() 12 | 13 | # volume rendering 14 | mlab.pipeline.volume(mlab.pipeline.scalar_field(s)) 15 | mlab.show() 16 | 17 | 18 | # change the data limits 19 | mlab.pipeline.volume(mlab.pipeline.scalar_field(s), vmin=0, vmax=0.8) 20 | mlab.show() 21 | 22 | 23 | # cut planes 24 | mlab.pipeline.image_plane_widget(mlab.pipeline.scalar_field(s), 25 | plane_orientation='x_axes', 26 | slice_index=10) 27 | mlab.pipeline.image_plane_widget(mlab.pipeline.scalar_field(s), 28 | plane_orientation='y_axes', 29 | slice_index=10) 30 | mlab.outline() 31 | mlab.show() 32 | 33 | 34 | # combination 35 | src = mlab.pipeline.scalar_field(s) 36 | mlab.pipeline.iso_surface(src, contours=[s.min()+0.1*s.ptp(), ], opacity=0.1) # ptp is the range 37 | mlab.pipeline.iso_surface(src, contours=[s.max()-0.1*s.ptp(), ],) 38 | mlab.pipeline.image_plane_widget(src, 39 | plane_orientation='z_axes', 40 | slice_index=10) 41 | 42 | mlab.show() 43 | -------------------------------------------------------------------------------- /examples/mayavi/mayavi-vector.py: -------------------------------------------------------------------------------- 1 | # http://docs.enthought.com/mayavi/mayavi/mlab_case_studies.html 2 | 3 | import numpy as np 4 | 5 | from mayavi import mlab 6 | 7 | x, y, z = np.mgrid[0:1:20j, 0:1:20j, 0:1:20j] 8 | 9 | u = np.sin(np.pi*x) * np.cos(np.pi*z) 10 | v = -2*np.sin(np.pi*y) * np.cos(2*np.pi*z) 11 | w = np.cos(np.pi*x)*np.sin(np.pi*z) + np.cos(np.pi*y)*np.sin(2*np.pi*z) 12 | 13 | 14 | # a quiver field 15 | mlab.quiver3d(u, v, w) 16 | mlab.outline() 17 | mlab.show() 18 | 19 | 20 | # thin things out -- this doesn't seem to work? 21 | src = mlab.pipeline.vector_field(u, v, w) 22 | #mlab.pipeline.vectors(src, mask_points=20, scale_factor=1.) # keep only one point out of 20 23 | #mlab.outline() 24 | #mlab.show() 25 | 26 | 27 | mlab.pipeline.vector_cut_plane(src, mask_points=2, scale_factor=3) 28 | mlab.outline() 29 | mlab.show() 30 | 31 | 32 | # isosurfaces of the magnitude -- doesn't work 33 | #magnitude = mlab.pipeline.extract_vector_norm(src) 34 | #mlab.pipeline.iso_surface(magnitude, contours=[1.9, 0.5]) 35 | #mlab.outline() 36 | #mlab.show() 37 | 38 | 39 | mlab.figure(fgcolor=(0., 0., 0.), bgcolor=(1, 1, 1)) 40 | src = mlab.pipeline.vector_field(u, v, w) 41 | magnitude = mlab.pipeline.extract_vector_norm(src) 42 | 43 | # We apply the following modules on the magnitude object, in order to 44 | # be able to display the norm of the vectors, eg as the color. 45 | iso = mlab.pipeline.iso_surface(magnitude, contours=[1.9, ], opacity=0.3) 46 | 47 | #vec = mlab.pipeline.vectors(magnitude, mask_points=40, 48 | # line_width=1, 49 | # color=(.8, .8, .8), 50 | # scale_factor=4.) 51 | 52 | flow = mlab.pipeline.streamline(magnitude, seedtype='plane', 53 | seed_visible=False, 54 | seed_scale=0.5, 55 | seed_resolution=1, 56 | linetype='ribbon',) 57 | 58 | vcp = mlab.pipeline.vector_cut_plane(magnitude, mask_points=2, 59 | scale_factor=4, 60 | colormap='jet', 61 | plane_orientation='x_axes') 62 | mlab.show() 63 | 64 | 65 | -------------------------------------------------------------------------------- /examples/modules/simple/my_module.py: -------------------------------------------------------------------------------- 1 | 2 | print "this statement executes upon import" 3 | 4 | def fun_A(): 5 | """ print some text """ 6 | print "in fun_A" 7 | 8 | def fun_B(): 9 | """ print some different text """ 10 | print "in fun_B" 11 | 12 | if __name__ == "__main__": 13 | import sys 14 | print "arguments: ", sys.argv[1:] 15 | 16 | fun_A() 17 | fun_B() 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /examples/numerical-basics/overflow/overflow.f90: -------------------------------------------------------------------------------- 1 | program overflow 2 | 3 | integer i, iold 4 | !integer*2 i, iold 5 | 6 | iold = -1 7 | i = 0 8 | do while (i > iold) 9 | iold = i 10 | i = i+1 11 | enddo 12 | 13 | print *, i 14 | 15 | end program overflow 16 | 17 | -------------------------------------------------------------------------------- /examples/numerical-basics/overflow/overflow.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | iold = -1 4 | i = 1 5 | 6 | type_init = type(i) 7 | print("type currently: ", type_init) 8 | 9 | while (i > iold): 10 | print(i) 11 | iold = i 12 | i *= 2 13 | 14 | if (not type(i) == type_init): 15 | print("type changed, now: ", type(i)) 16 | break 17 | 18 | print(i) 19 | -------------------------------------------------------------------------------- /examples/packaging/distutils/foo/foo.py: -------------------------------------------------------------------------------- 1 | def foo(): 2 | print("you made it here!") 3 | 4 | 5 | -------------------------------------------------------------------------------- /examples/packaging/distutils/foo/setup.py: -------------------------------------------------------------------------------- 1 | from distutils.core import setup 2 | setup(name='foo', 3 | version='1.0', 4 | py_modules=['foo'], 5 | ) 6 | -------------------------------------------------------------------------------- /examples/packaging/example/mytest/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | This is my simple test module for demonstrating packaging 3 | """ 4 | 5 | #from mytest.demo import demo 6 | #from mytest.util import msg 7 | 8 | -------------------------------------------------------------------------------- /examples/packaging/example/mytest/demo/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/examples/packaging/example/mytest/demo/__init__.py -------------------------------------------------------------------------------- /examples/packaging/example/mytest/demo/demo.py: -------------------------------------------------------------------------------- 1 | def show(): 2 | print("this is my demo") 3 | 4 | def test(x): 5 | print("x = {}".format(x)) 6 | -------------------------------------------------------------------------------- /examples/packaging/example/mytest/util/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/examples/packaging/example/mytest/util/__init__.py -------------------------------------------------------------------------------- /examples/packaging/example/mytest/util/msg.py: -------------------------------------------------------------------------------- 1 | def fail(s): 2 | print("ERROR: {}".format(s)) 3 | 4 | def warn(s): 5 | print("WARNING: {}".format(s)) 6 | -------------------------------------------------------------------------------- /examples/packaging/setuptools/foo2/foo2/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | this is my foo2 test package 3 | """ 4 | 5 | # make these available into the parent namespace 6 | from foo2.foo import * 7 | 8 | -------------------------------------------------------------------------------- /examples/packaging/setuptools/foo2/foo2/foo.py: -------------------------------------------------------------------------------- 1 | def foo(): 2 | print("you made it here!") 3 | 4 | 5 | -------------------------------------------------------------------------------- /examples/packaging/setuptools/foo2/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | setup(name="foo2", 3 | version="1.0", 4 | description="this is a setuptools test example", 5 | packages=["foo2"], 6 | author="Michael Zingale", 7 | author_email="michael.zingale@stonybrook.edu", 8 | license="BSD" 9 | ) 10 | -------------------------------------------------------------------------------- /examples/packaging/single_file/example.py: -------------------------------------------------------------------------------- 1 | _hidden = "you may not see this" 2 | 3 | def demo(): 4 | print("this is a single file demo") 5 | 6 | 7 | if __name__ == "__main__": 8 | print("in the main block -- you are running from the commandline") 9 | demo() 10 | 11 | -------------------------------------------------------------------------------- /examples/python-snippets/README: -------------------------------------------------------------------------------- 1 | These are basic examples that are posted to the discussion forum 2 | throughout the semester. -------------------------------------------------------------------------------- /examples/python-snippets/advanced/looplistdelete.post: -------------------------------------------------------------------------------- 1 | Be careful when looping over items in a list and deleting them. You 2 | need to make a copy first: 3 | 4 | a_tmp = a[:] 5 | for a in a_tmp: 6 | ... 7 | -------------------------------------------------------------------------------- /examples/python-snippets/advanced/mail.post: -------------------------------------------------------------------------------- 1 | The following lines will send an e-mail: 2 | 3 | 4 | import smtplib 5 | from email.mime.text import MIMEText 6 | 7 | sender = "your e-mail address here" 8 | receiver = "your e-mail address here" 9 | 10 | subject = "python e-mail" 11 | 12 | body = """ 13 | your e-mail body goes here 14 | """ 15 | 16 | msg = MIMEText(body) 17 | msg['Subject'] = subject 18 | msg['From'] = sender 19 | msg['To'] = receiver 20 | 21 | try: 22 | smtpObj = smtplib.SMTP('localhost') 23 | smtpObj.sendmail(sender, receiver, msg.as_string()) 24 | except SMTPException: 25 | sys.exit("ERROR sending mail") 26 | 27 | -------------------------------------------------------------------------------- /examples/python-snippets/advanced/regex.post: -------------------------------------------------------------------------------- 1 | One topic we won't have time to dive deeply in is regular expressions. 2 | This is a shorthand syntax for pattern matching in strings. In 3 | python, the "re" module provides support for regular expressions. 4 | Here's an example: 5 | 6 | 7 | import re 8 | strings = [r"this is my string", 9 | r"this is a different string"] 10 | 11 | # this is the pattern that we will match -- it has 3 groups 12 | re_test = r"<(\w*)>(.*)" 13 | 14 | for s in strings: 15 | a = re.search(re_test, s) 16 | if not a == None: 17 | if a.group(1) == a.group(3): 18 | # we found a match 19 | print "string in '{}' tags is: {}".format(a.group(1), a.group(2)) 20 | 21 | 22 | This will find XML-like tags, this is text in the tag and 23 | extra the text associated with each tag. 24 | 25 | If you remove the "*" after the "\w", it will restrict itself to 26 | single-character tags. 27 | 28 | 29 | This webpage: 30 | 31 | http://txt2re.com/ 32 | 33 | will help you design a regular expression for whatever type of 34 | operation you want to do. 35 | 36 | 37 | Games are even devised around finding complex regexs: 38 | 39 | http://xkcd.com/1313/ 40 | 41 | (note the hover text there has a regular expression that supposedly 42 | will correctly match all the winners of all US Presidental elections, 43 | but not the losers) -- anyone what to try it? 44 | -------------------------------------------------------------------------------- /examples/python-snippets/advanced/regex.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | strings = [r"this is my string", 4 | r"this is a different string", 5 | r"multicharacter tag"] 6 | 7 | # this is the pattern that we will match -- it has 3 groups 8 | re_test = r"<(\w*)>(.*)" 9 | 10 | 11 | for s in strings: 12 | a = re.search(re_test, s) 13 | 14 | if not a == None: 15 | if a.group(1) == a.group(3): 16 | # we found a match 17 | print("string in '{}' tags is: {}".format(a.group(1), a.group(2))) 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /examples/python-snippets/advanced/zip.post: -------------------------------------------------------------------------------- 1 | Here's another simple example that shows how to use zip() to merge two 2 | lists, element by element into a list of tuples, and how to use the 3 | ".split()" method on a string to split it into its component words: 4 | 5 | >>> a = range(10) 6 | >>> print a 7 | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 8 | >>> b = "this is my nice long string".split() 9 | >>> print b 10 | ['this', 'is', 'my', 'nice', 'long', 'string'] 11 | >>> for n, w in zip(a, b): 12 | ....: print n, w 13 | ....: 14 | 0 this 15 | 1 is 16 | 2 my 17 | 3 nice 18 | 4 long 19 | 5 string 20 | -------------------------------------------------------------------------------- /examples/python-snippets/basics/class-example.py: -------------------------------------------------------------------------------- 1 | class Box(object): 2 | def __init__(self, width, height): 3 | self.width = width 4 | self.height = height 5 | 6 | def area(self): 7 | return self.width * self.height 8 | 9 | 10 | boxes = [] 11 | for n in range(1, 10): 12 | boxes.append(Box(2*n, 4*n)) 13 | 14 | 15 | for b in boxes: 16 | print(b.area()) 17 | 18 | 19 | big_boxes = [b for b in boxes if b.area() > 100.] 20 | print big_boxes 21 | -------------------------------------------------------------------------------- /examples/python-snippets/basics/escapesequences.post: -------------------------------------------------------------------------------- 1 | In class, we saw the escape sequence "\n" that generated a new line 2 | when printed. There are many other escape sequences. You can find 3 | a list here: 4 | 5 | https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals 6 | 7 | Here's a fun one -- to get your code to beep, do: 8 | 9 | print("\a") 10 | 11 | -------------------------------------------------------------------------------- /examples/python-snippets/basics/functionfunction.post: -------------------------------------------------------------------------------- 1 | Python functions are objects too. Here's an example of passing a 2 | function to a function. There's a other things to note here: 3 | 4 | 1. we use sys.exit() to abort if no function is supplied to execute() 5 | 6 | 2. we can use the "{}" syntax we saw with print in normal strings too. 7 | 8 | 9 | import sys 10 | 11 | def execute(x, function=None): 12 | if function == None: 13 | sys.exit("ERROR: no function supplied") 14 | 15 | return function(x) 16 | 17 | 18 | def test_function(x): 19 | a = "you passed in {}".format(x) 20 | return a 21 | 22 | 23 | print execute("test", function=test_function) 24 | 25 | 26 | -------------------------------------------------------------------------------- /examples/python-snippets/basics/in.post: -------------------------------------------------------------------------------- 1 | We say the "in" operator in class to loop over members of a list, e.g.: 2 | 3 | for a in [0, 1, 2, 3]: 4 | ... 5 | 6 | but in can also be used to test if a string contains a substring: 7 | 8 | 9 | >>> mystring = "this is my string" 10 | >>> "this" in mystring 11 | True 12 | >>> "that" in mystring 13 | False 14 | -------------------------------------------------------------------------------- /examples/python-snippets/basics/shallowcopy.post: -------------------------------------------------------------------------------- 1 | We briefly discussed shallow copies in class: 2 | 3 | >>> a = [1, 2, [3,4], 5] 4 | >>> b = a[:] 5 | >>> print id(a) 6 | 140022054383056 7 | >>> print id(b) 8 | 140022054485312 9 | >>> 10 | >>> print a[2] 11 | [3, 4] 12 | >>> print id(a[2]) 13 | 140022054381760 14 | >>> print id(b[2]) 15 | 140022054381760 16 | >>> 17 | >>> 18 | >>> a[2][0] = "changed" 19 | >>> print a 20 | [1, 2, ['changed', 4], 5] 21 | >>> print b 22 | [1, 2, ['changed', 4], 5] 23 | 24 | notice that the list in the list is not a copy, but they both point to 25 | the same list, so this is shallow in that sense. 26 | -------------------------------------------------------------------------------- /examples/python-snippets/basics/stringsmutable.post: -------------------------------------------------------------------------------- 1 | Strings in python are immutable -- that means that they cannot be 2 | changed. You can perform an operation on a string and produce a new 3 | string as a result. 4 | 5 | Remember, that the id() function can tell you about where a quantity 6 | exists in memory. 7 | 8 | Consider the following: 9 | 10 | In [1]: a = "this is my string" 11 | 12 | In [2]: print(id(a)) 13 | 139676110774200 14 | 15 | In [3]: a = a.replace("this", "that") 16 | 17 | In [4]: print(id(a)) 18 | 139676095173496 19 | 20 | Here we see that even though we stored the result of a.replace() back 21 | into a, id() shows us that it is pointing to a different location in 22 | memory. That means that our new string "that is my string" is in a 23 | different place in memory from our old string. 24 | 25 | -------------------------------------------------------------------------------- /examples/python-snippets/basics/zip-ex.py: -------------------------------------------------------------------------------- 1 | a = ["one", "two", "three", "four", "five"] 2 | b = [0, 9, 10, 11, 12] 3 | 4 | for x in zip(a, b): 5 | print x 6 | 7 | -------------------------------------------------------------------------------- /examples/python-snippets/numpy/functionfunction.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | def execute(x, function=None): 4 | if function == None: 5 | sys.exit("ERROR: no function supplied") 6 | 7 | return function(x) 8 | 9 | 10 | def test_function(x): 11 | a = "you passed in {}".format(x) 12 | return a 13 | 14 | 15 | print execute("test", function=test_function) 16 | -------------------------------------------------------------------------------- /examples/python-snippets/numpy/simple-exercise.txt: -------------------------------------------------------------------------------- 1 | Here's a simple exercise to play around with some numpy concepts. 2 | 3 | 1. create a function that takes a 1-d array of floating point values, 4 | x, and returns some mathematical operation on them (e.g. sin(x), or 5 | something like that) 6 | 7 | 2. in your main program, create x as evenly spaced numbers between 8 | some xmin and xmax 9 | 10 | 3. call your function on your vector x 11 | 12 | 4. compute the derivative of your function by differencing. Remember 13 | from calculus that f' = (f(x+h) - f(x))/h -- you can difference 14 | adjacent function values 15 | 16 | 5. compare the numerical derivative you computed with the analytic 17 | derivative (so you'll need to create an fprime(x) function too that 18 | has the analytic derivative of your original function). 19 | 20 | 21 | If you do this, post your code here. 22 | -------------------------------------------------------------------------------- /examples/python-snippets/resources.txt: -------------------------------------------------------------------------------- 1 | Common Python Mistakes: 2 | 3 | http://www.toptal.com/python/top-10-mistakes-that-python-programmers-make 4 | 5 | -------------------------------------------------------------------------------- /examples/scipy/FFT/cleaned.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/examples/scipy/FFT/cleaned.png -------------------------------------------------------------------------------- /examples/scipy/FFT/convolve.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import matplotlib.pyplot as plt 3 | from scipy import signal 4 | 5 | def main(): 6 | 7 | data = np.loadtxt("signal.txt") 8 | 9 | x = data[:,0] 10 | sig = data[:,2] 11 | orig = data[:,1] 12 | 13 | N = len(x) 14 | 15 | window = signal.gaussian(N, 20.0) 16 | window /= np.sum(window) 17 | clean = signal.convolve(sig, window, mode="same") 18 | 19 | plt.plot(x, clean) 20 | plt.plot(x, orig) 21 | plt.savefig("cleaned.png") 22 | 23 | 24 | 25 | if __name__ == "__main__": 26 | main() 27 | -------------------------------------------------------------------------------- /examples/scipy/FFT/gaussian.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/examples/scipy/FFT/gaussian.png -------------------------------------------------------------------------------- /examples/scipy/FFT/make_signal.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import matplotlib.pyplot as plt 3 | 4 | # make a signal that we will convolve 5 | 6 | def f(x, L): 7 | A = L/10.0 8 | return 2*np.sin(2*np.pi*x/L) + x*(L-x)**2/L**3 * np.cos(x) + 5*x*(L-x)/L**2 + A/2 + 0.1*A*np.sin(13*np.pi*x/L) 9 | 10 | 11 | N = 2048 12 | L = 50.0 13 | 14 | x = np.linspace(0, L, N, endpoint=False) 15 | f = f(x, L) 16 | fnew = f + 0.5*np.random.randn(N) 17 | 18 | with open("signal.txt", "w") as fo: 19 | for n in range(N): 20 | fo.write("{:20} {:20} {:20}\n".format(x[n], f[n], fnew[n])) 21 | 22 | plt.plot(x, f) 23 | plt.plot(x, fnew, zorder=-100) 24 | 25 | 26 | 27 | plt.savefig("test.png") 28 | -------------------------------------------------------------------------------- /examples/scipy/FFT/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/examples/scipy/FFT/test.png -------------------------------------------------------------------------------- /examples/scipy/ODEs/chaotic_pendulum.py: -------------------------------------------------------------------------------- 1 | """Solve the chaotic damped driven pendulum using the newer SciPy IVP 2 | ODE interfaces. Passing optional arguments is now done using the 3 | functools partial. 4 | """ 5 | 6 | import matplotlib.pyplot as plt 7 | import numpy as np 8 | from scipy.integrate import solve_ivp 9 | 10 | from functools import partial 11 | 12 | 13 | def rhs(t, Y, q, omega_d, b): 14 | """ damped driven pendulum system derivatives. Here, Y = (theta, omega) are 15 | the solution variables. """ 16 | f = np.zeros_like(Y) 17 | 18 | f[0] = Y[1] 19 | f[1] = -q*Y[1] - np.sin(Y[0]) + b*np.cos(omega_d*t) 20 | 21 | return f 22 | 23 | def restrict_theta(theta): 24 | """ convert theta to be restricted to lie between -pi and pi""" 25 | tnew = theta + np.pi 26 | tnew += -2.0*np.pi*np.floor(tnew/(2.0*np.pi)) 27 | tnew -= np.pi 28 | return tnew 29 | 30 | def integrate(Y0, tmax, q, omega_d, b, dt=0.05): 31 | 32 | r = solve_ivp(partial(rhs, q=q, omega_d=omega_d, b=b), 33 | (0.0, tmax), 34 | Y0, 35 | dense_output=True) 36 | 37 | t = np.arange(0.0, tmax, dt) 38 | return t, r.sol(t) 39 | 40 | 41 | if __name__ == "__main__": 42 | q = 0.5 43 | omega_d = 2./3. 44 | b = 1.5 45 | 46 | T_d = 2.0*np.pi/omega_d 47 | 48 | t, Y = integrate([np.radians(60), 0.0], 50*T_d, q, omega_d, b, dt=T_d/200.0) 49 | 50 | plt.plot(t, restrict_theta(Y[0,:])) 51 | plt.savefig("damped_pendulum.png") 52 | -------------------------------------------------------------------------------- /examples/testing/pytest/class/test_class.py: -------------------------------------------------------------------------------- 1 | # a test class is useful to hold data that we might want set up 2 | # for every test. 3 | 4 | import numpy as np 5 | from numpy.testing import assert_array_equal 6 | 7 | class TestClassExample: 8 | @classmethod 9 | def setup_class(cls): 10 | """ this is run once for each class, before any tests """ 11 | pass 12 | 13 | @classmethod 14 | def teardown_class(cls): 15 | """ this is run once for each class, after all tests """ 16 | pass 17 | 18 | def setup_method(self): 19 | """ this is run before each of the test methods """ 20 | self.a = np.arange(24).reshape(6, 4) 21 | 22 | def teardown_method(self): 23 | """ this is run after each of the test methods """ 24 | pass 25 | 26 | def test_max(self): 27 | assert self.a.max() == 23 28 | 29 | def test_flat(self): 30 | assert_array_equal(self.a.flat, np.arange(24)) 31 | -------------------------------------------------------------------------------- /examples/testing/pytest/fixtures/shopping_cart.py: -------------------------------------------------------------------------------- 1 | INVENTORY_TEXT = """ 2 | apple, 0.60 3 | banana, 0.20 4 | grapefruit, 0.75 5 | grapes, 1.99 6 | kiwi, 0.50 7 | lemon, 0.20 8 | lime, 0.25 9 | mango, 1.50 10 | papaya, 2.95 11 | pineapple, 3.50 12 | blueberries, 1.99 13 | blackberries, 2.50 14 | peach, 0.50 15 | plum, 0.33 16 | clementine, 0.25 17 | cantaloupe, 3.25 18 | pear, 1.25 19 | quince, 0.45 20 | orange, 0.60 21 | """ 22 | 23 | # this will be a global -- convention is all caps 24 | INVENTORY = {} 25 | for line in INVENTORY_TEXT.splitlines(): 26 | if line.strip() == "": 27 | continue 28 | item, price = line.split(",") 29 | INVENTORY[item] = float(price) 30 | 31 | 32 | class Item: 33 | """ an item to buy """ 34 | 35 | def __init__(self, name, quantity=1): 36 | """keep track of an item that is in our inventory""" 37 | if name not in INVENTORY: 38 | raise ValueError("invalid item name") 39 | self.name = name 40 | self.quantity = quantity 41 | 42 | def __repr__(self): 43 | return f"{self.name}: {self.quantity}" 44 | 45 | def __eq__(self, other): 46 | """check if the items have the same name""" 47 | return self.name == other.name 48 | 49 | def __add__(self, other): 50 | """add two items together if they are the same type""" 51 | if self.name == other.name: 52 | return Item(self.name, self.quantity + other.quantity) 53 | raise ValueError("names don't match") 54 | -------------------------------------------------------------------------------- /examples/testing/pytest/fixtures/test_item.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | import shopping_cart 3 | 4 | 5 | @pytest.fixture 6 | def a(): 7 | return shopping_cart.Item("apple", 10) 8 | 9 | @pytest.fixture 10 | def b(): 11 | return shopping_cart.Item("banana", 20) 12 | 13 | @pytest.fixture 14 | def c(): 15 | return shopping_cart.Item("apple", 20) 16 | 17 | def test_add(a, c): 18 | # modifies a 19 | a += c 20 | assert a.quantity == 30 21 | 22 | def test_repr(a, b, c): 23 | # receives unmodified a 24 | assert repr(a) == "apple: 10" 25 | assert repr(b) == "banana: 20" 26 | assert repr(c) == "apple: 20" 27 | 28 | def test_equality(a, b, c): 29 | assert a != b 30 | assert a == c 31 | 32 | def test_invalid_add(a, b): 33 | with pytest.raises(ValueError, match="names don't match"): 34 | a + b 35 | 36 | def test_invalid_name(): 37 | with pytest.raises(ValueError, match="invalid item name"): 38 | d = shopping_cart.Item("dog") 39 | -------------------------------------------------------------------------------- /examples/testing/pytest/fixtures/test_list.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | @pytest.fixture 4 | def numbers(): 5 | return [] 6 | 7 | @pytest.fixture 8 | def append_1(numbers): 9 | numbers.append(1) 10 | 11 | @pytest.fixture 12 | def append_2(numbers, append_1): 13 | numbers.append(2) 14 | 15 | def test_initial(numbers): 16 | assert numbers == [] 17 | 18 | def test_append_1(numbers, append_1): 19 | assert numbers == [1] 20 | 21 | def test_append_2(numbers, append_2): 22 | assert numbers == [1, 2] 23 | -------------------------------------------------------------------------------- /examples/testing/pytest/function_setup/test_function_setup.py: -------------------------------------------------------------------------------- 1 | # to run this, in this directory, simply do 2 | # 3 | # pytest -vs . 4 | 5 | def multiply(a, b): 6 | return a*b 7 | 8 | def setup_function(function): 9 | # this is called before every function 10 | print("setting up {}".format(function)) 11 | 12 | def teardown_function(function): 13 | # this is called after every function 14 | print("done") 15 | 16 | def test_multiply(): 17 | assert multiply(4, 6) == 24 18 | 19 | def test_multiply2(): 20 | assert multiply(5, 6) == 24 21 | 22 | -------------------------------------------------------------------------------- /examples/testing/pytest/simple/test_simple.py: -------------------------------------------------------------------------------- 1 | # to run this, in this directory, simply do 2 | # 3 | # pytest . 4 | 5 | def multiply(a, b): 6 | return a*b 7 | 8 | def test_multiply(): 9 | assert multiply(4, 6) == 24 10 | 11 | def test_multiply2(): 12 | assert multiply(5, 6) == 24 13 | 14 | -------------------------------------------------------------------------------- /other/50-mayavi/NOTES: -------------------------------------------------------------------------------- 1 | There seems to be a bug with Mayavi on Fedora for now... 2 | 3 | https://bugzilla.redhat.com/show_bug.cgi?id=1081494 4 | 5 | Mayavi bug: 6 | 7 | https://github.com/enthought/mayavi/issues/74 8 | 9 | 10 | start ipython with --gui=wx 11 | http://docs.enthought.com/mayavi/mayavi/mlab_running_scripts.html#running-mlab-scripts 12 | 13 | -------------------------------------------------------------------------------- /other/50-mayavi/mayavi.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/other/50-mayavi/mayavi.pdf -------------------------------------------------------------------------------- /other/LectureNotebooks: -------------------------------------------------------------------------------- 1 | https://github.com/jrjohansson/scientific-python-lectures 2 | -------------------------------------------------------------------------------- /other/scientific-python-lectures-master/.gitignore: -------------------------------------------------------------------------------- 1 | *.py[cod] 2 | 3 | # C extensions 4 | *.so 5 | 6 | # Packages 7 | *.egg 8 | *.egg-info 9 | dist 10 | build 11 | eggs 12 | parts 13 | bin 14 | var 15 | sdist 16 | develop-eggs 17 | .installed.cfg 18 | lib 19 | lib64 20 | 21 | # Installer logs 22 | pip-log.txt 23 | 24 | # Unit test / coverage reports 25 | .coverage 26 | .tox 27 | nosetests.xml 28 | 29 | # Translations 30 | *.mo 31 | 32 | # Mr Developer 33 | .mr.developer.cfg 34 | .project 35 | .pydevproject 36 | -------------------------------------------------------------------------------- /other/scientific-python-lectures-master/README.md: -------------------------------------------------------------------------------- 1 | Lectures on scientific computing with Python 2 | ============================================ 3 | 4 | A set of lectures on scientific computing with Python, using IPython notebooks. 5 | 6 | To open these notebooks in IPython, download the files to a directory on your computer and from that directory run: 7 | 8 | $ ipython notebook 9 | 10 | This will open a new page in your browser with a list of the available notebooks. 11 | 12 | Online read-only versions 13 | ========================= 14 | 15 | Use the following links: 16 | 17 | * [Lecture-0 Scientific Computing with Python](http://nbviewer.ipython.org/urls/raw.github.com/jrjohansson/scientific-python-lectures/master/Lecture-0-Scientific-Computing-with-Python.ipynb) 18 | * [Lecture-1 Introduction to Python Programming](http://nbviewer.ipython.org/urls/raw.github.com/jrjohansson/scientific-python-lectures/master/Lecture-1-Introduction-to-Python-Programming.ipynb) 19 | * [Lecture-2 Numpy - multidimensional data arrays](http://nbviewer.ipython.org/urls/raw.github.com/jrjohansson/scientific-python-lectures/master/Lecture-2-Numpy.ipynb) 20 | * [Lecture-3 Scipy - Library of scientific algorithms](http://nbviewer.ipython.org/urls/raw.github.com/jrjohansson/scientific-python-lectures/master/Lecture-3-Scipy.ipynb) 21 | * [Lecture-4 Matplotlib - 2D and 3D plotting](http://nbviewer.ipython.org/urls/raw.github.com/jrjohansson/scientific-python-lectures/master/Lecture-4-Matplotlib.ipynb) 22 | * [Lecture-5 Sympy - Symbolic algebra](http://nbviewer.ipython.org/urls/raw.github.com/jrjohansson/scientific-python-lectures/master/Lecture-5-Sympy.ipynb) 23 | * [Lecture-6A C and Fortran integration](http://nbviewer.ipython.org/urls/raw.github.com/jrjohansson/scientific-python-lectures/master/Lecture-6A-Fortran-and-C.ipynb) 24 | * [Lecture-6B HPC](http://nbviewer.ipython.org/urls/raw.github.com/jrjohansson/scientific-python-lectures/master/Lecture-6B-HPC.ipynb) 25 | * [Lecture-7 Revision Control Software](http://nbviewer.ipython.org/urls/raw.github.com/jrjohansson/scientific-python-lectures/master/Lecture-7-Revision-Control-Software.ipynb) 26 | 27 | 28 | License 29 | ======= 30 | 31 | This work is licensed under a [Creative Commons Attribution 3.0 Unported License.](http://creativecommons.org/licenses/by/3.0/) 32 | -------------------------------------------------------------------------------- /other/scientific-python-lectures-master/cy_dcumsum.pyx: -------------------------------------------------------------------------------- 1 | 2 | cimport numpy 3 | 4 | def dcumsum(numpy.ndarray[numpy.float64_t, ndim=1] a, numpy.ndarray[numpy.float64_t, ndim=1] b): 5 | cdef int i, n = len(a) 6 | b[0] = a[0] 7 | for i from 1 <= i < n: 8 | b[i] = b[i-1] + a[i] 9 | return b 10 | -------------------------------------------------------------------------------- /other/scientific-python-lectures-master/dcumsum.f: -------------------------------------------------------------------------------- 1 | c File dcumsum.f 2 | subroutine dcumsum(a, b, n) 3 | double precision a(n) 4 | double precision b(n) 5 | integer n 6 | cf2py intent(in) :: a 7 | cf2py intent(out) :: b 8 | cf2py intent(hide) :: n 9 | 10 | b(1) = a(1) 11 | do 100 i=2, n 12 | b(i) = b(i-1) + a(i) 13 | 100 continue 14 | end 15 | -------------------------------------------------------------------------------- /other/scientific-python-lectures-master/dprod.f: -------------------------------------------------------------------------------- 1 | 2 | subroutine dprod(x, y, n) 3 | 4 | double precision x(n), y 5 | y = 1.0 6 | 7 | do 100 i=1, n 8 | y = y * x(i) 9 | 100 continue 10 | end 11 | -------------------------------------------------------------------------------- /other/scientific-python-lectures-master/dprod.pyf: -------------------------------------------------------------------------------- 1 | python module dprod ! in 2 | interface ! in :dprod 3 | subroutine dprod(x,y,n) ! in :dprod:dprod.f 4 | double precision dimension(n), intent(in) :: x 5 | double precision, intent(out) :: y 6 | integer, optional,check(len(x)>=n),depend(x),intent(in) :: n=len(x) 7 | end subroutine dprod 8 | end interface 9 | end python module dprod 10 | -------------------------------------------------------------------------------- /other/scientific-python-lectures-master/filename.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/other/scientific-python-lectures-master/filename.png -------------------------------------------------------------------------------- /other/scientific-python-lectures-master/functions.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | void hello(int n); 5 | 6 | double dprod(double *x, int n); 7 | 8 | void dcumsum(double *a, double *b, int n); 9 | 10 | void 11 | hello(int n) 12 | { 13 | int i; 14 | 15 | for (i = 0; i < n; i++) 16 | { 17 | printf("C says hello\n"); 18 | } 19 | } 20 | 21 | 22 | double 23 | dprod(double *x, int n) 24 | { 25 | int i; 26 | double y = 1.0; 27 | 28 | for (i = 0; i < n; i++) 29 | { 30 | y *= x[i]; 31 | } 32 | 33 | return y; 34 | } 35 | 36 | void 37 | dcumsum(double *a, double *b, int n) 38 | { 39 | int i; 40 | 41 | b[0] = a[0]; 42 | for (i = 1; i < n; i++) 43 | { 44 | b[i] = a[i] + b[i-1]; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /other/scientific-python-lectures-master/functions.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/other/scientific-python-lectures-master/functions.o -------------------------------------------------------------------------------- /other/scientific-python-lectures-master/functions.py: -------------------------------------------------------------------------------- 1 | 2 | import numpy 3 | import ctypes 4 | 5 | _libfunctions = numpy.ctypeslib.load_library('libfunctions', '.') 6 | 7 | _libfunctions.hello.argtypes = [ctypes.c_int] 8 | _libfunctions.hello.restype = ctypes.c_void_p 9 | 10 | _libfunctions.dprod.argtypes = [numpy.ctypeslib.ndpointer(dtype=numpy.float), ctypes.c_int] 11 | _libfunctions.dprod.restype = ctypes.c_double 12 | 13 | _libfunctions.dcumsum.argtypes = [numpy.ctypeslib.ndpointer(dtype=numpy.float), numpy.ctypeslib.ndpointer(dtype=numpy.float), ctypes.c_int] 14 | _libfunctions.dcumsum.restype = ctypes.c_void_p 15 | 16 | def hello(n): 17 | return _libfunctions.hello(int(n)) 18 | 19 | def dprod(x, n=None): 20 | if n is None: 21 | n = len(x) 22 | x = numpy.asarray(x, dtype=numpy.float) 23 | return _libfunctions.dprod(x, int(n)) 24 | 25 | def dcumsum(a, n): 26 | a = numpy.asarray(a, dtype=numpy.float) 27 | b = numpy.empty(len(a), dtype=numpy.float) 28 | _libfunctions.dcumsum(a, b, int(n)) 29 | return b 30 | -------------------------------------------------------------------------------- /other/scientific-python-lectures-master/hello.py: -------------------------------------------------------------------------------- 1 | import hellofortran 2 | 3 | hellofortran.hellofortran(5) 4 | -------------------------------------------------------------------------------- /other/scientific-python-lectures-master/hellofortran.f: -------------------------------------------------------------------------------- 1 | C File hellofortran.f 2 | subroutine hellofortran (n) 3 | integer n 4 | 5 | do 100 i=0, n 6 | print *, "Fortran says hello" 7 | 100 continue 8 | end 9 | -------------------------------------------------------------------------------- /other/scientific-python-lectures-master/images/github-diff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/other/scientific-python-lectures-master/images/github-diff.png -------------------------------------------------------------------------------- /other/scientific-python-lectures-master/images/github-project-page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/other/scientific-python-lectures-master/images/github-project-page.png -------------------------------------------------------------------------------- /other/scientific-python-lectures-master/images/gitk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/other/scientific-python-lectures-master/images/gitk.png -------------------------------------------------------------------------------- /other/scientific-python-lectures-master/images/ipython-notebook-screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/other/scientific-python-lectures-master/images/ipython-notebook-screenshot.jpg -------------------------------------------------------------------------------- /other/scientific-python-lectures-master/images/ipython-screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/other/scientific-python-lectures-master/images/ipython-screenshot.jpg -------------------------------------------------------------------------------- /other/scientific-python-lectures-master/images/optimizing-what-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/other/scientific-python-lectures-master/images/optimizing-what-2.png -------------------------------------------------------------------------------- /other/scientific-python-lectures-master/images/optimizing-what.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/other/scientific-python-lectures-master/images/optimizing-what.png -------------------------------------------------------------------------------- /other/scientific-python-lectures-master/images/python-screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/other/scientific-python-lectures-master/images/python-screenshot.jpg -------------------------------------------------------------------------------- /other/scientific-python-lectures-master/images/scientific-python-stack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/other/scientific-python-lectures-master/images/scientific-python-stack.png -------------------------------------------------------------------------------- /other/scientific-python-lectures-master/images/spyder-screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/other/scientific-python-lectures-master/images/spyder-screenshot.jpg -------------------------------------------------------------------------------- /other/scientific-python-lectures-master/images/theory-experiment-computation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbu-python-class/python-science/242822639f61911c43f0ff7902814e18a21f6b4d/other/scientific-python-lectures-master/images/theory-experiment-computation.png -------------------------------------------------------------------------------- /other/scientific-python-lectures-master/run_hello_c.py: -------------------------------------------------------------------------------- 1 | 2 | import functions 3 | 4 | functions.hello(3) 5 | -------------------------------------------------------------------------------- /other/scientific-python-lectures-master/scripts/hello-world-in-swedish.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: UTF-8 -*- 3 | 4 | print("Hej världen!") 5 | -------------------------------------------------------------------------------- /other/scientific-python-lectures-master/scripts/hello-world.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | print("Hello world!") 4 | -------------------------------------------------------------------------------- /other/scientific-python-lectures-master/setup.py: -------------------------------------------------------------------------------- 1 | 2 | from distutils.core import setup 3 | from distutils.extension import Extension 4 | from Cython.Distutils import build_ext 5 | 6 | setup( 7 | cmdclass = {'build_ext': build_ext}, 8 | ext_modules = [Extension("cy_dcumsum", ["cy_dcumsum.pyx"])] 9 | ) 10 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.codespell] 2 | skip = "*.fodp,*.pdf,*.sty,.git,*/_build,*.c,*.f90,other" 3 | #ignore-words-list = "pres" 4 | 5 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | jupyter-book 2 | matplotlib 3 | basemap 4 | numpy 5 | sympy 6 | scipy 7 | keras 8 | tensorflow 9 | pydot 10 | graphviz 11 | scikit-learn 12 | sphinx-copybutton 13 | sphinx-prompt 14 | jupyterlab_myst 15 | 16 | -------------------------------------------------------------------------------- /syllabus/GNUmakefile: -------------------------------------------------------------------------------- 1 | EPStoPDF = epstopdf 2 | 3 | ALL: syllabus.pdf 4 | 5 | %.pdf: %.tex 6 | pdflatex $< 7 | pdflatex $< 8 | 9 | clean: 10 | $(RM) *.aux *.log 11 | $(RM) *~ 12 | 13 | .PHONY: clean 14 | --------------------------------------------------------------------------------