diff --git a/Gemfile b/Gemfile deleted file mode 100755 index 5230ce5..0000000 --- a/Gemfile +++ /dev/null @@ -1,21 +0,0 @@ -source 'https://rubygems.org' - -group :jekyll_plugins do - gem 'github-pages' - gem 'jekyll-feed', '~> 0.6' - - # Textbook plugins - gem 'jekyll-redirect-from' - gem 'jekyll-scholar' -end - -# Windows does not include zoneinfo files, so bundle the tzinfo-data gem -gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] - -# Performance-booster for watching directories on Windows -gem 'wdm', '~> 0.1.0' if Gem.win_platform? - -# Development tools -gem 'guard', '~> 2.14.2' -gem 'guard-jekyll-plus', '~> 2.0.2' -gem 'guard-livereload', '~> 2.5.2' diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index 3cfafaf..0000000 --- a/Gemfile.lock +++ /dev/null @@ -1,309 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - activesupport (4.2.11.1) - i18n (~> 0.7) - minitest (~> 5.1) - thread_safe (~> 0.3, >= 0.3.4) - tzinfo (~> 1.1) - addressable (2.8.0) - public_suffix (>= 2.0.2, < 5.0) - bibtex-ruby (4.4.7) - latex-decode (~> 0.0) - citeproc (1.0.9) - namae (~> 1.0) - citeproc-ruby (1.1.10) - citeproc (~> 1.0, >= 1.0.9) - csl (~> 1.5) - coderay (1.1.2) - coffee-script (2.4.1) - coffee-script-source - execjs - coffee-script-source (1.11.1) - colorator (1.1.0) - commonmarker (0.17.13) - ruby-enum (~> 0.5) - concurrent-ruby (1.1.5) - csl (1.5.0) - namae (~> 1.0) - csl-styles (1.0.1.9) - csl (~> 1.0) - dnsruby (1.61.3) - addressable (~> 2.5) - em-websocket (0.5.1) - eventmachine (>= 0.12.9) - http_parser.rb (~> 0.6.0) - ethon (0.12.0) - ffi (>= 1.3.0) - eventmachine (1.2.7) - execjs (2.7.0) - faraday (0.17.0) - multipart-post (>= 1.2, < 3) - ffi (1.11.1) - formatador (0.2.5) - forwardable-extended (2.6.0) - gemoji (3.0.1) - github-pages (202) - activesupport (= 4.2.11.1) - github-pages-health-check (= 1.16.1) - jekyll (= 3.8.5) - jekyll-avatar (= 0.6.0) - jekyll-coffeescript (= 1.1.1) - jekyll-commonmark-ghpages (= 0.1.6) - jekyll-default-layout (= 0.1.4) - jekyll-feed (= 0.11.0) - jekyll-gist (= 1.5.0) - jekyll-github-metadata (= 2.12.1) - jekyll-mentions (= 1.4.1) - jekyll-optional-front-matter (= 0.3.0) - jekyll-paginate (= 1.1.0) - jekyll-readme-index (= 0.2.0) - jekyll-redirect-from (= 0.14.0) - jekyll-relative-links (= 0.6.0) - jekyll-remote-theme (= 0.4.0) - jekyll-sass-converter (= 1.5.2) - jekyll-seo-tag (= 2.5.0) - jekyll-sitemap (= 1.2.0) - jekyll-swiss (= 0.4.0) - jekyll-theme-architect (= 0.1.1) - jekyll-theme-cayman (= 0.1.1) - jekyll-theme-dinky (= 0.1.1) - jekyll-theme-hacker (= 0.1.1) - jekyll-theme-leap-day (= 0.1.1) - jekyll-theme-merlot (= 0.1.1) - jekyll-theme-midnight (= 0.1.1) - jekyll-theme-minimal (= 0.1.1) - jekyll-theme-modernist (= 0.1.1) - jekyll-theme-primer (= 0.5.3) - jekyll-theme-slate (= 0.1.1) - jekyll-theme-tactile (= 0.1.1) - jekyll-theme-time-machine (= 0.1.1) - jekyll-titles-from-headings (= 0.5.1) - jemoji (= 0.10.2) - kramdown (= 1.17.0) - liquid (= 4.0.0) - listen (= 3.1.5) - mercenary (~> 0.3) - minima (= 2.5.0) - nokogiri (>= 1.10.4, < 2.0) - rouge (= 3.11.0) - terminal-table (~> 1.4) - github-pages-health-check (1.16.1) - addressable (~> 2.3) - dnsruby (~> 1.60) - octokit (~> 4.0) - public_suffix (~> 3.0) - typhoeus (~> 1.3) - guard (2.14.2) - formatador (>= 0.2.4) - listen (>= 2.7, < 4.0) - lumberjack (>= 1.0.12, < 2.0) - nenv (~> 0.1) - notiffany (~> 0.0) - pry (>= 0.9.12) - shellany (~> 0.0) - thor (>= 0.18.1) - guard-compat (1.2.1) - guard-jekyll-plus (2.0.2) - guard (~> 2.10, >= 2.10.3) - guard-compat (~> 1.1) - jekyll (>= 1.0.0) - guard-livereload (2.5.2) - em-websocket (~> 0.5) - guard (~> 2.8) - guard-compat (~> 1.0) - multi_json (~> 1.8) - html-pipeline (2.12.0) - activesupport (>= 2) - nokogiri (>= 1.4) - http_parser.rb (0.6.0) - i18n (0.9.5) - concurrent-ruby (~> 1.0) - jekyll (3.8.5) - addressable (~> 2.4) - colorator (~> 1.0) - em-websocket (~> 0.5) - i18n (~> 0.7) - jekyll-sass-converter (~> 1.0) - jekyll-watch (~> 2.0) - kramdown (~> 1.14) - liquid (~> 4.0) - mercenary (~> 0.3.3) - pathutil (~> 0.9) - rouge (>= 1.7, < 4) - safe_yaml (~> 1.0) - jekyll-avatar (0.6.0) - jekyll (~> 3.0) - jekyll-coffeescript (1.1.1) - coffee-script (~> 2.2) - coffee-script-source (~> 1.11.1) - jekyll-commonmark (1.3.1) - commonmarker (~> 0.14) - jekyll (>= 3.7, < 5.0) - jekyll-commonmark-ghpages (0.1.6) - commonmarker (~> 0.17.6) - jekyll-commonmark (~> 1.2) - rouge (>= 2.0, < 4.0) - jekyll-default-layout (0.1.4) - jekyll (~> 3.0) - jekyll-feed (0.11.0) - jekyll (~> 3.3) - jekyll-gist (1.5.0) - octokit (~> 4.2) - jekyll-github-metadata (2.12.1) - jekyll (~> 3.4) - octokit (~> 4.0, != 4.4.0) - jekyll-mentions (1.4.1) - html-pipeline (~> 2.3) - jekyll (~> 3.0) - jekyll-optional-front-matter (0.3.0) - jekyll (~> 3.0) - jekyll-paginate (1.1.0) - jekyll-readme-index (0.2.0) - jekyll (~> 3.0) - jekyll-redirect-from (0.14.0) - jekyll (~> 3.3) - jekyll-relative-links (0.6.0) - jekyll (~> 3.3) - jekyll-remote-theme (0.4.0) - addressable (~> 2.0) - jekyll (~> 3.5) - rubyzip (>= 1.2.1, < 3.0) - jekyll-sass-converter (1.5.2) - sass (~> 3.4) - jekyll-scholar (5.16.0) - bibtex-ruby (~> 4.0, >= 4.0.13) - citeproc-ruby (~> 1.0) - csl-styles (~> 1.0) - jekyll (~> 3.0) - jekyll-seo-tag (2.5.0) - jekyll (~> 3.3) - jekyll-sitemap (1.2.0) - jekyll (~> 3.3) - jekyll-swiss (0.4.0) - jekyll-theme-architect (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-theme-cayman (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-theme-dinky (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-theme-hacker (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-theme-leap-day (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-theme-merlot (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-theme-midnight (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-theme-minimal (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-theme-modernist (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-theme-primer (0.5.3) - jekyll (~> 3.5) - jekyll-github-metadata (~> 2.9) - jekyll-seo-tag (~> 2.0) - jekyll-theme-slate (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-theme-tactile (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-theme-time-machine (0.1.1) - jekyll (~> 3.5) - jekyll-seo-tag (~> 2.0) - jekyll-titles-from-headings (0.5.1) - jekyll (~> 3.3) - jekyll-watch (2.2.1) - listen (~> 3.0) - jemoji (0.10.2) - gemoji (~> 3.0) - html-pipeline (~> 2.2) - jekyll (~> 3.0) - kramdown (1.17.0) - latex-decode (0.3.1) - liquid (4.0.0) - listen (3.1.5) - rb-fsevent (~> 0.9, >= 0.9.4) - rb-inotify (~> 0.9, >= 0.9.7) - ruby_dep (~> 1.2) - lumberjack (1.0.13) - mercenary (0.3.6) - method_source (0.9.2) - mini_portile2 (2.6.1) - minima (2.5.0) - jekyll (~> 3.5) - jekyll-feed (~> 0.9) - jekyll-seo-tag (~> 2.1) - minitest (5.13.0) - multi_json (1.14.1) - multipart-post (2.1.1) - namae (1.0.1) - nenv (0.3.0) - nokogiri (1.12.5) - mini_portile2 (~> 2.6.1) - racc (~> 1.4) - notiffany (0.1.3) - nenv (~> 0.1) - shellany (~> 0.0) - octokit (4.14.0) - sawyer (~> 0.8.0, >= 0.5.3) - pathutil (0.16.2) - forwardable-extended (~> 2.6) - pry (0.12.2) - coderay (~> 1.1.0) - method_source (~> 0.9.0) - public_suffix (3.1.1) - racc (1.5.2) - rb-fsevent (0.10.3) - rb-inotify (0.10.0) - ffi (~> 1.0) - rouge (3.11.0) - ruby-enum (0.7.2) - i18n - ruby_dep (1.5.0) - rubyzip (2.0.0) - safe_yaml (1.0.5) - sass (3.7.4) - sass-listen (~> 4.0.0) - sass-listen (4.0.0) - rb-fsevent (~> 0.9, >= 0.9.4) - rb-inotify (~> 0.9, >= 0.9.7) - sawyer (0.8.2) - addressable (>= 2.3.5) - faraday (> 0.8, < 2.0) - shellany (0.0.1) - terminal-table (1.8.0) - unicode-display_width (~> 1.1, >= 1.1.1) - thor (0.20.3) - thread_safe (0.3.6) - typhoeus (1.3.1) - ethon (>= 0.9.0) - tzinfo (1.2.5) - thread_safe (~> 0.1) - unicode-display_width (1.6.0) - -PLATFORMS - ruby - -DEPENDENCIES - github-pages - guard (~> 2.14.2) - guard-jekyll-plus (~> 2.0.2) - guard-livereload (~> 2.5.2) - jekyll-feed (~> 0.6) - jekyll-redirect-from - jekyll-scholar - tzinfo-data - -BUNDLED WITH - 1.17.2 diff --git a/Guardfile b/Guardfile deleted file mode 100755 index fbf9911..0000000 --- a/Guardfile +++ /dev/null @@ -1,8 +0,0 @@ -guard 'jekyll-plus', serve: true do - watch /.*/ - ignore /^_site/ -end - -guard 'livereload' do - watch /.*/ -end diff --git a/Makefile b/Makefile deleted file mode 100755 index cc37ba9..0000000 --- a/Makefile +++ /dev/null @@ -1,34 +0,0 @@ -.PHONY: help book clean serve - -help: - @echo "Please use 'make ' where is one of:" - @echo " install to install the necessary dependencies for jupyter-book to build" - @echo " book to convert the content/ folder into Jekyll markdown in _build/" - @echo " clean to clean out site build files" - @echo " runall to run all notebooks in-place, capturing outputs with the notebook" - @echo " serve to serve the repository locally with Jekyll" - @echo " build to build the site HTML and store in _site/" - @echo " site to build the site HTML, store in _site/, and serve with Jekyll" - - -install: - jupyter-book install ./ - -book: - jupyter-book build ./ - -runall: - jupyter-book run ./content - -clean: - python scripts/clean.py - -serve: - bundle exec guard - -build: - jupyter-book build ./ --overwrite - -site: build - bundle exec jekyll build - touch _site/.nojekyll diff --git a/_bibliography/references.bib b/_bibliography/references.bib deleted file mode 100755 index cbf9b01..0000000 --- a/_bibliography/references.bib +++ /dev/null @@ -1,56 +0,0 @@ ---- ---- - -@inproceedings{holdgraf_evidence_2014, - address = {Brisbane, Australia, Australia}, - title = {Evidence for {Predictive} {Coding} in {Human} {Auditory} {Cortex}}, - booktitle = {International {Conference} on {Cognitive} {Neuroscience}}, - publisher = {Frontiers in Neuroscience}, - author = {Holdgraf, Christopher Ramsay and de Heer, Wendy and Pasley, Brian N. and Knight, Robert T.}, - year = {2014} -} - -@article{holdgraf_rapid_2016, - title = {Rapid tuning shifts in human auditory cortex enhance speech intelligibility}, - volume = {7}, - issn = {2041-1723}, - url = {http://www.nature.com/doifinder/10.1038/ncomms13654}, - doi = {10.1038/ncomms13654}, - number = {May}, - journal = {Nature Communications}, - author = {Holdgraf, Christopher Ramsay and de Heer, Wendy and Pasley, Brian N. and Rieger, Jochem W. and Crone, Nathan and Lin, Jack J. and Knight, Robert T. and Theunissen, Frédéric E.}, - year = {2016}, - pages = {13654}, - file = {Holdgraf et al. - 2016 - Rapid tuning shifts in human auditory cortex enhance speech intelligibility.pdf:C\:\\Users\\chold\\Zotero\\storage\\MDQP3JWE\\Holdgraf et al. - 2016 - Rapid tuning shifts in human auditory cortex enhance speech intelligibility.pdf:application/pdf} -} - -@inproceedings{holdgraf_portable_2017, - title = {Portable learning environments for hands-on computational instruction using container-and cloud-based technology to teach data science}, - volume = {Part F1287}, - isbn = {978-1-4503-5272-7}, - doi = {10.1145/3093338.3093370}, - abstract = {© 2017 ACM. There is an increasing interest in learning outside of the traditional classroom setting. This is especially true for topics covering computational tools and data science, as both are challenging to incorporate in the standard curriculum. These atypical learning environments offer new opportunities for teaching, particularly when it comes to combining conceptual knowledge with hands-on experience/expertise with methods and skills. Advances in cloud computing and containerized environments provide an attractive opportunity to improve the effciency and ease with which students can learn. This manuscript details recent advances towards using commonly-Available cloud computing services and advanced cyberinfrastructure support for improving the learning experience in bootcamp-style events. We cover the benets (and challenges) of using a server hosted remotely instead of relying on student laptops, discuss the technology that was used in order to make this possible, and give suggestions for how others could implement and improve upon this model for pedagogy and reproducibility.}, - booktitle = {{ACM} {International} {Conference} {Proceeding} {Series}}, - author = {Holdgraf, Christopher Ramsay and Culich, A. and Rokem, A. and Deniz, F. and Alegro, M. and Ushizima, D.}, - year = {2017}, - keywords = {Teaching, Bootcamps, Cloud computing, Data science, Docker, Pedagogy} -} - -@article{holdgraf_encoding_2017, - title = {Encoding and decoding models in cognitive electrophysiology}, - volume = {11}, - issn = {16625137}, - doi = {10.3389/fnsys.2017.00061}, - abstract = {© 2017 Holdgraf, Rieger, Micheli, Martin, Knight and Theunissen. Cognitive neuroscience has seen rapid growth in the size and complexity of data recorded from the human brain as well as in the computational tools available to analyze this data. This data explosion has resulted in an increased use of multivariate, model-based methods for asking neuroscience questions, allowing scientists to investigate multiple hypotheses with a single dataset, to use complex, time-varying stimuli, and to study the human brain under more naturalistic conditions. These tools come in the form of “Encoding” models, in which stimulus features are used to model brain activity, and “Decoding” models, in which neural features are used to generated a stimulus output. Here we review the current state of encoding and decoding models in cognitive electrophysiology and provide a practical guide toward conducting experiments and analyses in this emerging field. Our examples focus on using linear models in the study of human language and audition. We show how to calculate auditory receptive fields from natural sounds as well as how to decode neural recordings to predict speech. The paper aims to be a useful tutorial to these approaches, and a practical introduction to using machine learning and applied statistics to build models of neural activity. The data analytic approaches we discuss may also be applied to other sensory modalities, motor systems, and cognitive systems, and we cover some examples in these areas. In addition, a collection of Jupyter notebooks is publicly available as a complement to the material covered in this paper, providing code examples and tutorials for predictive modeling in python. The aimis to provide a practical understanding of predictivemodeling of human brain data and to propose best-practices in conducting these analyses.}, - journal = {Frontiers in Systems Neuroscience}, - author = {Holdgraf, Christopher Ramsay and Rieger, J.W. and Micheli, C. and Martin, S. and Knight, R.T. and Theunissen, F.E.}, - year = {2017}, - keywords = {Decoding models, Encoding models, Electrocorticography (ECoG), Electrophysiology/evoked potentials, Machine learning applied to neuroscience, Natural stimuli, Predictive modeling, Tutorials} -} - -@book{ruby, - title = {The Ruby Programming Language}, - author = {Flanagan, David and Matsumoto, Yukihiro}, - year = {2008}, - publisher = {O'Reilly Media} -} \ No newline at end of file diff --git a/_build/features/Intro_clases.html b/_build/features/Intro_clases.html deleted file mode 100644 index 4a256e1..0000000 --- a/_build/features/Intro_clases.html +++ /dev/null @@ -1,3126 +0,0 @@ ---- -redirect_from: - - "/features/intro-clases" -interact_link: content/features/Intro_clases.ipynb -kernel_name: python3 -kernel_path: content/features -has_widgets: false -title: |- - Clases -pagenum: 26 -prev_page: - url: /features/statistics.html -next_page: - url: -suffix: .ipynb -search: de la clase el que python es n en una un se objeto y com para self super del boldsymbol k como class vector con funcin puede ell solutions main mtodos mtodo por ser google clases programa ejemplo los x colab atributos nombre las def func z ldots instancia atributo dentro integers espacio org ayuda especial subclass sum begin align alpha beta end left right decir cada objetos list diferentes pueda name desde inicializar dataframe init none automticamente var object research github tambin variables nombres usar drive programacin general funcional debe ejecuta continuacin especiales herencia web cases frac text even - -comment: "***PROGRAMMATICALLY GENERATED, DO NOT EDIT. SEE ORIGINAL FILES IN /content***" ---- - -
-
Clases
-
-
- -
-
-

Open In Colab

- -
-
-
-
- -
- -
-
-

Clases

En Python, todo es un objeto, es decir, una instancia o realización de un clase. Cada objeto tiene unos métodos:

-
objeto.metodo(...)
-que corresponde  a funciónes internas del objeto, y también puede tener _atributos_:
-
-
objeto.atributo
-
-

que son variables internas dentro del objeto: self.atributo=.....

-

Algunos objetos en Python también pueden recibir parámetros de entrada a modo de claves de un diccionario interno del objeto

-
objeto['key']='value'
-
-

entro otras muchas propiedades

-

Ejemplos de objetos son:

-
    -
  • int: Enteros
  • -
  • float: Números punto flotante (floating point numbers)
  • -
  • str: Cadenas de caracteres
  • -
  • list: Listas
  • -
  • dict: Diccionarios.
  • -
-

Si el tipo de objeto es conocido, uno pude comprobar si un objeto determinado corresponde a ese tipo con isinstance:

- -
-
-
-
- -
- -
-
- -
-
-
s='hola mundo'
-print('Is `s` an string?: {}'.format( isinstance(s,str)) )
-print('Is `s` a float?: {}'.format( isinstance(s,float)) )
-
- -
-
-
- -
-
- -
-
- -
-
Is `s` an string?: True
-Is `s` a float?: False
-
-
-
-
-
-
- -
-
- -
- -
-
-

Dentro del paradigma de objetos es posible agrupar diferentes conjuntos de variables de modo que el nombre de un atributo a método adquiere dos partes, una parte principal, que en el análogo con el nombre completo de una persona podríamos asimilar a su apellido, y el método o atributo, que sería como el primer nombre, separados por un punto:

-
    -
  • Método: last_name.first_name()
  • -
  • Atributo: last_name.first_name.
  • -
-

Esto nos permite tener objetos dentro de un programa con igual nombre, pero diferente appellido. Como por ejemplo, los diferentes $\cos(x)$ que vienen en los diferentes módulos matématicos implementados en Python. Por eso es recomendado cargar los módulos manteniendo el espacio de nombres (que en nuestra analogía sería el espacio de apellidos). Cuando el modulo tenga un nombre muy largo (más de cuatro caracteres), se puede usar una abreviatura lo suficientemente original para evitar que pueda ser sobreescrita por un nuevo objeto:

- -
-
-
-
- -
- -
-
- -
-
-
import math
-import numpy as np
-k=3 #N/m
-m=2 #Kg
-A=3 #m
-t=2 #s
-ω=np.sqrt(k/m) #rad/s
-#ver https://pyformat.info/
-print('x(t)={:.2f} m'.format( 
-    A*np.cos( ω*t )
-     ))
-print('x(t)={:.2f} m'.format( 
-    A*math.cos( ω*t )
-     ))
-
- -
-
-
- -
-
- -
-
- -
-
x(t)=-2.31 m
-x(t)=-2.31 m
-
-
-
-
-
-
- -
-
- -
- -
-
-

Note que import math as m entraría en conflicto con la definición de m en m=2

- -
-
-
-
- -
- -
-
-

La forma recomendada de importar los diferentes módulos y el uso de sus métodos y atributos suele resumirse en Cheat Sheets. Para Python científico recomendamos las elaboradas por Data Camp, que pueden consultarse aquí

- -
-
-
-
- -
- -
-
-

Para programación de Python en general se recomienda el estándar PEP 8 de Python

- -
-
-
-
- -
- -
-
-

Antes de comenzar con las clases, es conveniente resumir el paradigma de programación funcional:

- -
-
-
-
- -
- -
-
-

Programación funcional

En cálculo científico el paradigma funcional, en el cual el programa se escribe en términos de funciones, suele ser suficiente.

-

El esqueleto de un programa funcional es típicamente del siguiente tipo

-
#!/usr/bin/user/env python3
-import somemodule as sm
-def func1(...):
-    '''
-    Ayuda func1
-   '''
-    .....
-
-def func2(...):
-    '''
-    Ayuda func2
-    '''
-    .....
-
-
-def main(...):
-    '''
-    Ayuda función principal
-    '''
-    x=func1(...)
-    y=func2(x)
-
-if __name__='__main__':
-    z=main(...)
-    print('El resultado final es: {}'.format(z))
-
-

Para su diseño, el programa se debe separar sus partes independientes y para cada una de ellas se debe definir una función.

-

La función ideal es una que se pueda reutilizar facilamente en otro contexto.

-

La última función, main(...) combina todas las anteriores para entregar el resultado final del programa.

-

La instrucción

-
if __name__='__main__'
-
-

permite que el programa pueda ser usado también como un módulo de Python, es decir que se pueda cargar desde otro programa con el import. En tal caso, la variable -interna de Python __name__ es diferente a la cadena de caracteres '__main__' y esa parte del programa no se ejecuta. Dentro de Jupyter:

- -
-
-
-
- -
- -
-
- -
-
-
__name__
-
- -
-
-
- -
-
- -
-
- - - -
-
'__main__'
-
- -
-
-
-
- -
-
- -
- -
-
-

Ejemplo módulo

- -
-
-
-
- -
- -
-
- -
-
-
%%writefile example.py
-#!/usr/bin/env python3
-print( 'check __name__: {}'.format(__name__))
-
-def hola():
-    print( 'check __name__ como módulo: {}'.format(__name__))
-    print('mundo')
-    
-if __name__=='__main__':
-    hola()
-
- -
-
-
- -
-
- -
-
- -
-
Overwriting example.py
-
-
-
-
-
-
- -
-
- -
- -
-
-

ls funciona

- -
-
-
-
- -
- -
-
- -
-
-
ls -l example.py
-
- -
-
-
- -
-
- -
-
- -
-
-rwxr-xr-x 1 restrepo restrepo 205 Jun 16 12:20 example.py*
-
-
-
-
-
-
- -
-
- -
- -
-
-

cat funciona

- -
-
-
-
- -
- -
-
- -
-
-
cat example.py 
-
- -
-
-
- -
-
- -
-
- -
-
#!/usr/bin/env python3
-print( 'check __name__: {}'.format(__name__))
-
-def hola():
-    print( 'check __name__ como módulo: {}'.format(__name__))
-    print('mundo')
-    
-if __name__=='__main__':
-    hola()
-
-
-
-
-
-
- -
-
- -
- -
-
-

Cambia los permisos a ejecución

- -
-
-
-
- -
- -
-
- -
-
-
! chmod a+x example.py
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
ls -l example.py
-
- -
-
-
- -
-
- -
-
- -
-
-rwxr-xr-x 1 restrepo restrepo 205 Jun 16 12:20 example.py*
-
-
-
-
-
-
- -
-
- -
- -
-
-

Corre el programa desde la consola

- -
-
-
-
- -
- -
-
- -
-
-
!./example.py
-
- -
-
-
- -
-
- -
-
- -
-
check __name__: __main__
-check __name__ como módulo: __main__
-mundo
-
-
-
-
-
-
- -
-
- -
- -
-
-

Uso como módulo

- -
-
-
-
- -
- -
-
- -
-
-
import example
-
- -
-
-
- -
-
- -
-
- -
-
check __name__: example
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
example.hola()
-
- -
-
-
- -
-
- -
-
- -
-
check __name__ como módulo: example
-mundo
-
-
-
-
-
-
- -
-
- -
- -
-
-

Ejecutarlo desde una celda de Jupyter es equivalente a ejecutarlo desde la consola

- -
-
-
-
- -
- -
-
- -
-
-
#!/usr/bin/env python3
-print( 'check __name__: {}'.format(__name__))
-
-def hola():
-    print('mundo')
-    
-if __name__=='__main__':
-    hola()
-
- -
-
-
- -
-
- -
-
- -
-
check __name__: __main__
-mundo
-
-
-
-
-
-
- -
-
- -
- -
-
-

Clases

-
-
-
-
- -
- -
-
-

Aunque en Python se puede trabajar directamente con objetos, en general un objeto es una instancia de un clase. Es decir, debe incializarse a partir de una Clase. Esto típicamente involucra ejecutar varios métodos e inicializar varios atributos bajo el espacio de nombres del objeto incializado. Por ejemplo, para inicializar las clases 'int', 'float', 'str', 'list','dict'

- -
-
-
-
- -
- -
-
- -
-
-
n=int() # ⬄ to n=0
-n
-
- -
-
-
- -
-
- -
-
- - - -
-
0
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
x=float(3) # ⬄ x=3.
-x
-
- -
-
-
- -
-
- -
-
- - - -
-
3.0
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
l=list() # ⬄ l=[]
-l
-
- -
-
-
- -
-
- -
-
- - - -
-
[]
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
d=dict() # ⬄ d={}
-d
-
- -
-
-
- -
-
- -
-
- - - -
-
{}
-
- -
-
-
-
- -
-
- -
- -
-
-

La principal motivación para escribir una clase en lugar de una función, es que la clase puede ser la base para generar nuevas clases que hereden los métodos y atributos de la clase original.

- -
-
-
-
- -
- -
-
-

Por ejemplo el DataFrame de Pandas es una clase que puede ser inicializada de múltiples formas. Además, está diseñada para que pueda ser extendida facilmente: https://pandas.pydata.org/pandas-docs/stable/development/extending.html

- -
-
-
-
- -
- -
-
- -
-
-
import pandas as pd
-
- -
-
-
- -
-
- -
- -
-
-
In[1]: pd.DataFrame??
-...
-class DataFrame(NDFrame):
-    ...
-    # ----------------------------------------------------------------------
-    # Constructors
-
-    def __init__(self, data=None, index=None, columns=None, dtype=None,
-                 copy=False):
-        if data is None:
-            ...
-
- -
-
-
-
- -
- -
-
-

Como puede verse, un DataFrame es una subclase (es decir, un caso especial) de NDFrame.

- -
-
-
-
- -
- -
-
-

Una instancia u objeto de la clase DataFrame, df a continuación, se puede inicializar de diferentes maneras

- -
-
-
-
- -
- -
-
- -
-
-
df=pd.DataFrame()
-df
-
- -
-
-
- -
-
- -
-
- - - -
-
(0, 0)
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
df=pd.DataFrame([{'A':1,'B':2}])
-df
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - -
AB
012
-
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
df=pd.DataFrame({'A':[1],'B':[2]})
-df
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - -
AB
012
-
-
- -
-
-
-
- -
-
- -
- -
-
-

Programación por clases

-
-
-
-
- -
- -
-
-

Una clase se puede pensar como un conjuto de funciones y atributos que comparten algo común.

-

Algunas veces, cuando la complejidad del problema se puede descomponer en una estructura de capas, donde la capa interna es la mas simple y las capas más externas van aumentando la complejidad, pude ser conveniente pensar en una estructura de clases.

-

De hecho, la clase básica puede heredar todas sus propiedades a subclases basadas en ella.

-

El espacio de nombres asociado a la clase se define con el nombre génerico de self el cual toma el nombre de las instancia (objeto) asociada a la inicialización de la clase. -Las variables globales de la clase pasán a ser automáticamente atributos del objeto, y nuevo atributos de pueden definir dentro del espacio de nombres self dentro de cada función de la clase.

-

Esqueleto:

-
class clasenueva:
-     '''
-     Ayuda de la clase
-    '''
-
-    var1='valor'
-    def func1(self,...):
-        '''
-        Ayuda del método
-        '''
-        self.var2='hola mundo'
-        ....
-    def func2(self,....):
-        '''
-        Ayuda del método
-        '''        
-        print(self.var1)
-        print(self.var2)
-        ....
-
-    def main(self,....):
-        ....
-if __name__=='__main__':
-         objetonuevo=clasenueva()
-         # self → objetonuevo
-        objetonuevo.main()
-
- -
-
-
-
- -
- -
-
-

Cada una de las funciones pasan a ser métodos de la clase, mientras que cada una de la variables globales y con espacio de nombre self pasan a ser atributos de la clase.

-

Ejemplo:

- -
-
-
-
- -
- -
-
- -
-
-
class clasenueva:
-    var='hola'
-    var2=[]
-    def main(self):
-        self.var=self.var+' mundo'
-        self.var3=self.var2+[3]
-        print(self.var)
-
- -
-
-
- -
-
- -
- -
-
-

Creación del objeto c, de manera que selfc. c es una instancia de la clase clasenueva a continuación:

- -
-
-
-
- -
- -
-
- -
-
-
c=clasenueva()
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
c.var
-
- -
-
-
- -
-
- -
-
- - - -
-
'hola'
-
- -
-
-
-
- -
-
- -
- -
-
-

main es un método de la clase

- -
-
-
-
- -
- -
-
- -
-
-
c.main()
-
- -
-
-
- -
-
- -
-
- -
-
hola mundo
-
-
-
-
-
-
- -
-
- -
- -
-
-

var es un atributo de la clase

- -
-
-
-
- -
- -
-
- -
-
-
c.var
-
- -
-
-
- -
-
- -
-
- - - -
-
'hola mundo'
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
c.var3
-
- -
-
-
- -
-
- -
-
- - - -
-
[3]
-
- -
-
-
-
- -
-
- -
- -
-
-

Para la creación de clases disponemos de métodos especiales que podemos definir para adicionar "magia" a nuestras clases. Estas están simpre rodeadas de un doble guión bajo, por ejemplo: __init__ o __lt__. Una lista completa de ellos con su explicación de uso se puede encontrar en 1.

-

Resaltamos a continuación algunos de ellos

-
    -
  • __init__: Se ejecuta automáticamente al inicializar la clase
  • -
  • __call__: Se ejecuta cuando el objeto creado es usado como función
  • -
- -
-
-
-
- -
- -
-
-

Herencia

Los métodos especiales se heredan automáticamente desde la clase inicial, que llamaremos super clase inicializamos la clase con la super clase como argumento, es decir, en forma genérica como:

-
class subclass(superclass):
-    ...
-
- -
-
-
-
- -
- -
-
-

Clase vector

-
-
-
-
- -
- -
-
-

Comenzaremos definiendo un alias de clase list que llameremos vector y que funcione exactamente igual que la clase lista. Todas los métodos especiales se heredan automáticamente

- -
-
-
-
- -
- -
-
- -
-
-
class vector(list):
-    pass
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
l=list()
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
v=vector()
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
v.append(1)
-v
-
- -
-
-
- -
-
- -
-
- - - -
-
[1]
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
l1=[1,2]
-l2=[3,4]
-l1+l2
-
- -
-
-
- -
-
- -
-
- - - -
-
[1, 2, 3, 4]
-
- -
-
-
-
- -
-
- -
- -
-
-

Vamos a inicializar dos instancias de la clase vector y comprobar que suman como listas

- -
-
-
-
- -
- -
-
- -
-
-
v1=vector(l1)
-v2=vector(l2)
-v1+v2
-
- -
-
-
- -
-
- -
-
- - - -
-
[1, 2, 3, 4]
-
- -
-
-
-
- -
-
- -
- -
-
-

Ahora reemplazaremos el método especial __add__ de la lista para que el operador + realice la suma vectorial:

- -
-
-
-
- -
- -
-
- -
-
-
class vector(list):
-    def __add__(self, other):
-        '''
-        __add__ asocia la operación del símbolo '+'
-        '''
-        return vector(map(lambda x,y: x+y, self, other))    
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
v1=vector(l1)
-v2=vector(l2)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
v1+v2
-
- -
-
-
- -
-
- -
-
- - - -
-
[4, 6]
-
- -
-
-
-
- -
-
- -
- -
-
-

Si lo que queremos es modificar el comportomiento de un método especial entonces debemos usar la función super.

-

Para mantener la herencia el comportamiento de los métodos de una clase inicial, ls super clase, se usa la función super que mantiene la herencia. Ver:

- -

super() gives you access to methods in a superclass from the subclass that inherits from it.

-

super() is the same as super(__class__, <first argument>): the first is the subclass, and the second parameter is an object that is an instance of that subclass.

-
-

La estructura general es como la siguiente, basada en Inherited class variable modification in Python:

-
class subclass(superclass):
-    def __special__(self,*args, **kwargs):
-        #Modifications to __especial__ here
-        ...
-        super(subclass, self).__special__(*args, **kwargs)
-    ...
-
- -
-
-
-
- -
- -
-
-

Como ejemplo, vamos a implemetar el atributo modulus a la clase vector dentro del método especial __init__:

- -
-
-
-
- -
- -
-
- -
-
-
import math
-class vector(list):
-    def __init__(self,*args, **kwargs):
-        '''
-        Add the modulus of a vector at initialization 
-        '''
-        try:
-            l=args[0]
-            self.modulus=math.sqrt( sum( map( lambda l: l*l,l )) )
-        except:
-            self.modulus=0
-        super(vector, self).__init__(*args, **kwargs)
-    def __add__(self, other):
-        '''
-        __add__ asocia la operación del símbolo '+'
-        '''
-        return vector(map(lambda x,y: x+y, self, other))        
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
v1=vector( l1 )
-v1
-
- -
-
-
- -
-
- -
-
- - - -
-
[3, 2]
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
v1.modulus
-
- -
-
-
- -
-
- -
-
- - - -
-
3.605551275463989
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
type(v1)
-
- -
-
-
- -
-
- -
-
- - - -
-
__main__.vector
-
- -
-
-
-
- -
-
- -
- -
-
-

Una implementación completa de la clase vector, adapta de vector: a list based vector class supporting elementwise operations (python recipe), se puede encontrar aquí

- -
-
-
-
- -
- -
-
-

Otro ejemplo

-
-
-
-
- -
- -
-
- -
-
-
class veterinaria:
-    def __init__(self,x):
-        self.tipo={'perro':'guau','gato':'miau'}
-        self.sonido=self.tipo.get(x)
-    def __call__(self,nombre):
-        if nombre=='greco':
-            print(self.sonido)
-        else:
-            print("grrr!!")
-    def color(self,nombre):
-        if nombre=='greco':
-            print('blanco')
-
- -
-
-
- -
-
- -
- -
-
-
    -
  • Cundo se inicializa la clase la función llamada __init__, se ejecuta automáticamente.
  • -
  • La función __call__ permite usar el objeto directamente como función, sin hacer referencia al método, que por supuesto es __call__
  • -
-

Hay muchos otros métodos especiales, que comienzan con un __.... Usar <TAB> a continuación para ver algunos

- -
-
-
-
- -
- -
-
- -
-
-
veterinaria.__
-
- -
-
-
- -
-
- -
- -
-
-

Para utilizar la clase, primero se debe incializar como un objeto. Crear la instancia de la clase.

-

Ejemplo: Crea la instancia mascotafeliz

- -
-
-
-
- -
- -
-
- -
-
-
mascotafeliz=veterinaria('perro')
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
mascotafeliz('greco')
-
- -
-
-
- -
-
- -
-
- -
-
guau
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
mascotafeliz.color('greco')
-
- -
-
-
- -
-
- -
-
- -
-
blanco
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
perro.tipo.get('vaca')
-
- -
-
-
- -
-
- -
- -
-
-

Herencia

-
-
-
-
- -
- -
-
- -
-
-
import pandas as pd
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
class finanzas(pd.DataFrame):
-    pass
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
f=finanzas()
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
type(f)
-
- -
-
-
- -
-
- -
-
- - - -
-
__main__.finanzas
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
f([{'A':1}])
-
- -
-
-
- -
-
- -
-
- -
-
----------------------------------------------------------------------------
-TypeError                                 Traceback (most recent call last)
-<ipython-input-47-d585aedd1152> in <module>()
-----> 1 f([{'A':1}])
-
-TypeError: 'finanzas' object is not callable
-
-
-
-
-
- -
-
- -
- -
-
-

Para realmente heradar hay que inicializarlo de forma especial con la función super

- -
-
-
-
- -
- -
-
- -
-
-
class hkdict(dict):
-    def __init__(self,*args, **kwargs):
-        super(hkdict, self).__init__(*args, **kwargs)
-    def has_key(self,k):
-        return k in self
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
d={'perro':'guau','gato':'miau'}
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
d.has_key('gato')
-
- -
-
-
- -
-
- -
-
- -
-
----------------------------------------------------------------------------
-AttributeError                            Traceback (most recent call last)
-<ipython-input-52-4598d173b43c> in <module>()
-----> 1 d.has_key('gato')
-
-AttributeError: 'dict' object has no attribute 'has_key'
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
dd=hkdict(d)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
dd.has_key('vaca')
-
- -
-
-
- -
-
- -
-
- - - -
-
False
-
- -
-
-
-
- -
-
- -
- -
-
-

Implementation of arXiv:1905.13729

See also: DOI: 10.1103/PhysRevD.101.095032

-

General solution to the U(1) anomaly equations

Let a vector $\boldsymbol{z}$ with $N$ integer entries such that -$$ \sum_{i=1}^N z_i=0\,,\qquad \sum_{i=1}^N z_i^3=0\,.$$ -We like to build this set of of $N$ from two subsets $\boldsymbol{\ell}$ and $\boldsymbol{k}$ with sizes

-\begin{align} -\operatorname{dim}(\boldsymbol{\ell})=& -\begin{cases} -\alpha=\frac{N}{2}-1\,, & \text{ if $N$ even } \\ -\beta=\frac{N-3}{2}\,, & \text{ if $N$ odd }\\ -\end{cases};& -\operatorname{dim}(\boldsymbol{k})=& -\begin{cases} -\alpha=\frac{N}{2}-1\,, & \text{ if $N$ even } \\ -\beta+1=\frac{N-1}{2}\,, & \text{ if $N$ odd }\\ -\end{cases}; -\end{align}
    -
  • $N$ even: Consider the following two examples of $\boldsymbol{z}$ with vector-like solutions, i.e, with opposite integeres which automatically satisfy the equations -\begin{align} -\boldsymbol{x}=&\left(\ell_{1}, {k}_{1}, \ldots, k_{\alpha},-\ell_{1},-k_{1}, \ldots,-k_{\alpha}\right)\\ -\boldsymbol{y}=&\left(0,0,\ell_{1}, \ldots, \ell_{\alpha},-\ell_1, \ldots,-\ell_{\alpha}\right)\,. -\end{align}
  • -
  • $N$ odd: Consider the two vector-like solutions -\begin{align} -\begin{array} -\boldsymbol{x}=&\left(0, k_{1}, \ldots, k_{\beta+1},-k_{1}, \ldots,-k_{\beta+1}\right) \\ -\boldsymbol{y}=&\left(\ell_{1}, \ldots, \ell_{\beta}, k_{1}, 0,-\ell_{1}, \ldots,-\ell_{\beta},-k_{1}\right) -\end{array} -\end{align}
  • -
-

From any of this, we can build a final $\boldsymbol{z}$ which can includes chiral solutions, i.e, non vector-like solutions

-$$ -\boldsymbol{x} \oplus \boldsymbol{y} \equiv\left(\sum_{i=1}^{N} x_{i} y_{i}^{2}\right)\boldsymbol{x}-\left(\sum_{i=1}^{N} x_{i}^{2} y_{i}\right)\boldsymbol{y}\,. -$$ -
-
-
-
- -
- -
-
-

Python implmentation

Obtain a numpy array z of N integers which satisfy the Diophantine equations

-
>>> z.sum()
-0
->>> (z**3).sum()
-0
-
-

The input is two lists l and k with any (N-3)/2 and (N-1)/2 integers for N odd, or N/2-1 and N/2-1 for N even (N>4). -The function is implemented below under the name: free(l,k)

-

Open In Colab

- -
-
-
-
- - - -
- -
-
- -
-
-
import pandas as pd
-import numpy as np
-from astropy.table import Table
-import itertools
-import sys
-import os
-from functools import reduce
-import warnings
-warnings.filterwarnings("ignore")
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
!pip install anomalies 2>/dev/null > /dev/null
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
from anomalies import anomaly
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
anomaly.free([-1,1],[4,-2])
-
- -
-
-
- -
-
- -
-
- - - -
-
array([  3,   3,   3, -12, -12,  15])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
anomaly.free.gcd
-
- -
-
-
- -
-
- -
-
- - - -
-
3
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
anomaly.free.simplified
-
- -
-
-
- -
-
- -
-
- - - -
-
array([ 1,  1,  1, -4, -4,  5])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
z=anomaly.free
-
- -
-
-
- -
-
- -
- -
-
-

Analysis

solutions class → Initialize the object to obtain anomaly free solutions for any set of N integers

- -
-
-
-
- -
- -
-
- -
-
-
#TODO: inherit from free class
-import sys
-def _get_chiral(q,q_max=np.inf):
-    #Normalize to positive minimum
-    if q[0]<0 or (q[0]==0 and q[1]<0):
-        q=-q
-    #Divide by GCD
-    GCD=np.gcd.reduce(q)
-    q=(q/GCD).astype(int)
-    if ( #not 0 in z and 
-          0 not in [ sum(p) for p in itertools.permutations(q, 2) ] and #avoid vector-like and multiple 0's
-          #q.size > np.unique(q).size and # check for at least a duplicated entry
-          np.abs(q).max()<=q_max
-           ):
-        return q,GCD
-    else:
-        return None,None
-class solutions(object):
-    '''
-    Obtain anomaly free solutions with N chiral fields
-    
-    Call the initialize object with N and get the solutions:
-    Example:
-    >>> s=solutions()
-    >>> s(6) # N = 6
-    
-    Redefine the self.chiral function to implement further restrictions:
-    inherit from this class and define the new chiral function
-    '''
-    def __init__(self,nmin=-2,nmax=2,zmax=np.inf):
-        self.nmin=nmin
-        self.nmax=nmax
-        self.zmax=zmax
-        self.CALL=False
-
-    def __call__(self,N,*args,**kwargs):
-        self.CALL=True
-        if N%2!=0: #odd
-            N_l=(N-3)//2
-            N_k=(N-1)//2
-        else: #even
-            N_l=N//2-1
-            N_k=N_l
-        r=range(self.nmin,self.nmax+1)
-        self.ls=list(itertools.product( *(r for i in range(N_l)) ))
-        self.ks=list(itertools.product( *(r for i in range(N_k)) ))
-        return self.chiral(*args,**kwargs)
-        
-        
-    def chiral(self,*args,**kwargs):
-        if not self.CALL:
-            sys.exit('Call the initialized object first:\n>>> s=solutions()\n>>> self(5)')
-        self.list=[]
-        solt=[]
-        for l in self.ls:
-            for k in self.ks:
-                l=list(l)
-                k=list(k)
-                q,gcd=_get_chiral( z(l,k) )
-                #print(z(l,k))
-                if q is not None and list(q) not in self.list and list(-q) not in self.list:
-                    self.list.append(list(q))
-                    solt.append({'l':l,'k':k,'z':list(q),'gcd':gcd})
-        return solt
-
- -
-
-
- -
-
- -
- -
-
-

Chiral solutions for l and k in the range [-2,2]

- -
-
-
-
- -
- -
-
- -
-
-
s=solutions()
-
- -
-
-
- -
-
- -
- -
-
-

solutions for $N=5$ integers

- -
-
-
-
- -
- -
-
- -
-
-
s(5)
-
- -
-
-
- -
-
- -
-
- - - -
-
[{'l': [-2], 'k': [-1, 2], 'z': [2, 4, -7, -9, 10], 'gcd': 1},
- {'l': [-2], 'k': [2, -1], 'z': [1, 5, -7, -8, 9], 'gcd': 4}]
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
pd.DataFrame(  s(5)  )
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
lkzgcd
0[-2][-1, 2][2, 4, -7, -9, 10]1
1[-2][2, -1][1, 5, -7, -8, 9]4
-
-
- -
-
-
-
- -
-
- -
- -
-
-

To filter solutions with duplicate or triplicate integers, let us create a class dark that inherits from solutions. Therefore, in the argument of the new class is the old class instead of just object

- -
-
-
-
- -
- -
-
- -
-
-
class dark(solutions):
-    '''
-    Modify the self.chiral function to obtain solutions
-    with either duplicate or triplicate integers
-    '''
-    def chiral(self,X=False,verbose=False,print_step=100000):
-        m=2
-        if X:
-            m=3
-        self.list=[]
-        solt=[]
-        tot=len(self.ls)*len(self.ks)
-        i=0
-        for l in self.ls:
-            for k in self.ks:
-                if verbose:
-                    i=i+1
-                    if i%print_step==0:
-                        print('{}/{}'.format(i,tot))
-                l=list(l)
-                k=list(k)
-                q,gcd=_get_chiral( z(l,k) )
-                #print(z(l,k))
-                if (q is not None and 
-                    list(q) not in self.list and list(-q) not in self.list and
-                    1 in [ len(set(p)) for p in itertools.permutations(q, m) ] and
-                    #q.size-np.unique(q).size>m
-                    np.abs(q).max()<=self.zmax
-                   ):
-                    self.list.append(list(q))
-                    solt.append({'l':l,'k':k,'z':list(q),'gcd':gcd})
-        return solt        
-
- -
-
-
- -
-
- -
- -
-
-

Chiral solutions with repeated integers

- -
-
-
-
- -
- -
-
- -
-
-
s=dark()
-
- -
-
-
- -
-
- -
- -
-
-

Example: Force solutions with triplicate integers

- -
-
-
-
- -
- -
-
- -
-
-
s(5)
-
- -
-
-
- -
-
- -
-
- - - -
-
[]
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
pd.DataFrame(   s(6,X=True)   )
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - -
lkzgcd
0[-2, 2][-2, -1][1, 1, 1, -4, -4, 5]8
-
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
%%time
-s=dark(nmin=-30,nmax=30)
-s(5)
-
- -
-
-
- -
-
- -
-
- -
-
CPU times: user 16.5 s, sys: 7.15 ms, total: 16.5 s
-Wall time: 16.6 s
-
-
-
-
-
-
- - - -
-
[]
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
%%time
-s=dark(nmin=-10,nmax=10,zmax=32)
-s(6,X=True,verbose=True)
-
- -
-
-
- -
-
- -
-
- -
-
100000/194481
-CPU times: user 19.9 s, sys: 0 ns, total: 19.9 s
-Wall time: 19.9 s
-
-
-
-
-
-
- - - -
-
[{'l': [-10, 5], 'k': [-2, 4], 'z': [1, 1, 1, -4, -4, 5], 'gcd': 1500},
- {'l': [-10, 5], 'k': [3, 4], 'z': [3, 3, 3, -10, -17, 18], 'gcd': 250}]
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
%%time
-s=dark(nmin=-21,nmax=21,zmax=32)
-slt=s(6,verbose=True,print_step=500000)
-
- -
-
-
- -
-
- -
-
- -
-
500000/3418801
-1000000/3418801
-1500000/3418801
-2000000/3418801
-2500000/3418801
-3000000/3418801
-CPU times: user 4min 20s, sys: 27.1 ms, total: 4min 20s
-Wall time: 4min 20s
-
-
-
-
-
-
- -
-
- -
- -
-
-

References

[1] A Guide to Python's Magic Methods

-

[2] https://realpython.com/python3-object-oriented-programming/

-

[3] Building Skills in Object-Oriented Design

-

[4] Ver también: https://gist.github.com/mcleonard/5351452

-

[5] Bhasin, Harsh. Python Basics: A Self-teaching Introduction. Stylus Publishing, LLC, 2018. [PDF] [Google Scholar]

- -
-
-
-
- - - - -
- \ No newline at end of file diff --git a/_build/features/LagrangePoly.html b/_build/features/LagrangePoly.html deleted file mode 100644 index 4474419..0000000 --- a/_build/features/LagrangePoly.html +++ /dev/null @@ -1,1157 +0,0 @@ ---- -redirect_from: - - "/features/lagrangepoly" -interact_link: content/features/LagrangePoly.ipynb -kernel_name: python3 -kernel_path: content/features -has_widgets: false -title: |- - Lagrange polynomials -pagenum: 12 -prev_page: - url: /features/interpolation.html -next_page: - url: /features/interpolation_details.html -suffix: .ipynb -search: x colab lagrange n l com polynomial f sympy implementation research google interpolation github form polynomials href restrepo computationalmethods blob master material lagrangepoly ipynb target parentimg src assets badge svg alt open pn sum xi wikipedia function qquad text based code gist folkertdev cca approx yil references en org wiki lagrangepolynomial interpolating example tree points degree numpy scipy simpy check expliclty p using lp polyl properties xj quad neq j objects python actividad fit cuatro puntos comprobando las propiedades del polinomio de - -comment: "***PROGRAMMATICALLY GENERATED, DO NOT EDIT. SEE ORIGINAL FILES IN /content***" ---- - -
-
Lagrange polynomials
-
-
- -
-
-

Open In Colab

- -
-
-
-
- -
- -
-
-

Interpolation polynomial in the Lagrange form

Open In Colab

-

Based on this code

-$$f(x)\approx P_n(x)\,,$$$$P_n(x) = \sum_{i=0}^n f(x_i)L_{n,i}(x) = \sum_{i=0}^n y_iL_{n,i}(x)$$

References: -Wikipedia

- -
-
-
-
- -
- -
-
-

We will use SymPy

-
-
-
-
- -
- -
-
- -
-
-
from sympy import simplify, symbols, expand, factor, sin, cos #..., lambdify, solve_poly_system
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
simplify('2/3+5/6')
-
- -
-
-
- -
-
- -
-
- - - -
-$\displaystyle \frac{3}{2}$ -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
x = symbols('x')
-expand('(x-1)*(x+1)')
-
- -
-
-
- -
-
- -
-
- - - -
-$\displaystyle x^{2} - 1$ -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
factor('x**2-1')
-
- -
-
-
- -
-
- -
-
- - - -
-$\displaystyle \left(x - 1\right) \left(x + 1\right)$ -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
x=symbols('x')
-
- -
-
-
- -
-
- -
- -
-
-

Implementation of the Lagrange interpolating polynomials and Lagrange polynomials in SymPy

-
-
-
-
- -
- -
-
- -
-
-
%%writefile LagrangePolynomial.py
-"""
-From: https://gist.github.com/folkertdev/084c53887c49a6248839
-A sympy-based Lagrange polynomial constructor. 
-
-Implementation of Lagrangian interpolating polynomial.
-See:
-
-   def lagrangePolynomial(xs, ys):
-
-Given two 1-D arrays `xs` and `ys,` returns the Lagrange interpolating
-polynomial through the points ``(xs, ys)``
-
-
-Given a set 1-D arrays of inputs and outputs, the lagrangePolynomial function 
-will construct an expression that for every input gives the corresponding output. 
-For intermediate values, the polynomial interpolates (giving varying results 
-based  on the shape of your input). 
-
-The Lagrangian polynomials can be obtained explicitly with (see below):
-   
-   def polyL(xs,j):
-   
-as sympy polynomial, and 
-
-    def L(xs,j):
-
-as Python functions.
-
-
-This is useful when the result needs to be used outside of Python, because the 
-expression can easily be copied. To convert the expression to a python function 
-object, use sympy.lambdify.
-"""
-from sympy import symbols, expand, lambdify, solve_poly_system
-#Python library for arithmetic with arbitrary precision
-from mpmath import tan, e
-
-import math
-
-from operator import mul
-from functools import reduce, lru_cache
-from itertools import chain
-
-# sympy symbols
-x = symbols('x')
-
-# convenience functions
-product = lambda *args: reduce(mul, *(list(args) + [1]))
-
-# test data
-labels = [(-3/2), (-3/4), 0, 3/4, 3/2]
-points = [math.tan(v) for v in labels]
-
-# this product may be reusable (when creating many functions on the same domain)
-# therefore, cache the result
-@lru_cache(16)
-def l(labels, j):
-    def gen(labels, j):
-        k = len(labels)
-        current = labels[j]
-        for m in labels:
-            if m == current:
-                continue
-            yield (x - m) / (current - m)
-    return expand(product(gen(labels, j)))
-
-def polyL(xs,j):
-    '''
-    Lagrange polynomials as sympy polynomial
-    xs: the n+1 nodes of the intepolation polynomial in the Lagrange Form
-    j: Is the j-th Lagrange polinomial for the specific xs.
-    '''
-    xs=tuple(xs)
-    return l(xs,j)
-
-def L(xs,j):
-    '''
-    Lagrange polynomials as python function
-    xs: the n+1 nodes of the intepolation polynomial in the Lagrange Form
-    j: Is the j-th Lagrange polinomial for the specific xs.
-    '''
-    return lambdify(x, polyL(xs,j) )
-
-def lagrangePolynomial(xs, ys):
-    '''
-    Given two 1-D arrays `x` and `w,` returns the Lagrange interpolating
-    polynomial through the points ``(x, w)``.
-
-    '''
-    # based on https://en.wikipedia.org/wiki/Lagrange_polynomial#Example_1
-    k = len(xs)
-    total = 0
-
-    # use tuple, needs to be hashable to cache
-    xs = tuple(xs)
-
-    for j, current in enumerate(ys):
-        t = current * l(xs, j)
-        total += t
-
-    return total
-
-
-
-
-def x_intersections(function, *args):
-    "Finds all x for which function(x) = 0"
-    # solve_poly_system seems more efficient than solve for larger expressions
-    return [var for var in chain.from_iterable(solve_poly_system([function], *args)) if (var.is_real)]
-
-def x_scale(function, factor):
-    "Scale function on the x-axis"
-    return functions.subs(x, x / factor)
-
-if __name__ == '__main__':
-    func = lagrangePolynomial(labels, points)
-
-    pyfunc = lambdify(x, func)
-
-    for a, b in zip(labels, points):
-        assert(pyfunc(a) - b < 1e-6)
-
- -
-
-
- -
-
- -
-
- -
-
Overwriting LagrangePolynomial.py
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
%pylab inline
-import pandas as pd
-import numpy as np
-import LagrangePolynomial as LP
-from scipy import interpolate
-
- -
-
-
- -
-
- -
-
- -
-
Populating the interactive namespace from numpy and matplotlib
-
-
-
-
-
-
- -
-
/usr/local/lib/python3.5/dist-packages/IPython/core/magics/pylab.py:160: UserWarning: pylab import has clobbered these variables: ['cos', 'sin']
-`%matplotlib` prevents importing * from pylab and numpy
-  "\n`%matplotlib` prevents importing * from pylab and numpy"
-
-
-
-
-
-
- -
-
- -
- -
-
-

Example of interpolation of tree points with a polynomial of degree 2

-
-
-
-
- -
- -
-
- -
-
-
df=pd.DataFrame({ 'X':[3,10,21.3],'Y':[8.,6.5,3.]}  )
-df
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
XY
03.08.0
110.06.5
221.33.0
-
-
- -
-
-
-
- -
-
- -
- -
-
-

Numpy implementation:

-
-
-
-
- -
- -
-
- -
-
-
coeffs=np.polyfit(df.X,df.Y,deg=2)
-
-P=np.poly1d(coeffs)
-plt.plot(df.X,df.Y,'ro')
-x=np.linspace(-8,30)
-plt.plot(x,P( x),'b-')
-#plt.grid()
-plt.ylim(0,12)
-
-print(np.poly1d(coeffs))
-
- -
-
-
- -
-
- -
-
- -
-
           2
--0.005216 x - 0.1465 x + 8.486
-
-
-
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Scipy implementation of the Interpolation polynomial in the Lagrange form

-
-
-
-
- -
- -
-
- -
-
-
interpolate.lagrange?
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
P=interpolate.lagrange(df.X,df.Y)
-print(P)
-
- -
-
-
- -
-
- -
-
- -
-
           2
--0.005216 x - 0.1465 x + 8.486
-
-
-
-
-
-
- -
-
- -
- -
-
-

Sympy implementation of the Interpolation polynomial in the Lagrange form

-
-
-
-
- -
- -
-
- -
-
-
LP.lagrangePolynomial(df.X,df.Y)
-
- -
-
-
- -
-
- -
-
- - - -
-$\displaystyle - 0.00521578136549848 x^{2} - 0.146480556534234 x + 8.48638370189219$ -
- -
-
-
-
- -
-
- -
- -
-
-

With this simpy implementation we can check expliclty that: -$$P_2(x) = L_{2,0}(x)f(x_0)+L_{2,1}(x)f(x_1)+L_{2,2}(x)f(x_2)$$

- -
-
-
-
- -
- -
-
-

a) By using sympy polynomials: LP.polyL:

- -
-
-
-
- -
- -
-
- -
-
-
LP.polyL( df.X,0)*df.Y[0]+LP.polyL( df.X,1)*df.Y[1]+LP.polyL( df.X,2)*df.Y[2]
-
- -
-
-
- -
-
- -
-
- - - -
-$\displaystyle - 0.00521578136549848 x^{2} - 0.146480556534234 x + 8.48638370189219$ -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
LP.polyL( df.X,0)
-
- -
-
-
- -
-
- -
-
- - - -
-$\displaystyle 0.0078064012490242 x^{2} - 0.244340359094457 x + 1.66276346604215$ -
- -
-
-
-
- -
-
- -
- -
-
-

As a function

- -
-
-
-
- -
- -
-
- -
-
-
def P_2(x,xs,ys):
-    return LP.L(xs,0)(x)*ys[0]+LP.L(xs,1)(x)*ys[1]+LP.L( xs,2)(x)*ys[2]
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
plt.plot(df.X,df.Y,'ro')
-x=np.linspace(-8,30)
-plt.plot(x,P_2( x,df.X,df.Y),'b-')
-#plt.grid()
-plt.ylim(0,12)
-
- -
-
-
- -
-
- -
-
- - - -
-
(0, 12)
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Lagrange polynomial properties

$$L_{n,i}(x_i) = 1\,,\qquad\text{and}\,,\qquad L_{n,i}(x_j) = 0\quad\text{for $i\neq j$}$$

- -
-
-
-
- -
- -
-
-

As sympy objects

- -
-
-
-
- -
- -
-
- -
-
-
L2_0=LP.polyL(df.X,0)
-L2_0
-
- -
-
-
- -
-
- -
-
- - - -
-$\displaystyle 0.0078064012490242 x^{2} - 0.244340359094457 x + 1.66276346604215$ -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
L2_0.as_poly()
-
- -
-
-
- -
-
- -
-
- - - -
-$\displaystyle \operatorname{Poly}{\left( 0.0078064012490242 x^{2} - 0.244340359094457 x + 1.66276346604215, x, domain=\mathbb{R} \right)}$ -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
L2_0.as_poly()(df.X[0])
-
- -
-
-
- -
-
- -
-
- - - -
-$\displaystyle 1.0$ -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
L2_0.as_poly()(df.X[1])
-
- -
-
-
- -
-
- -
-
- - - -
-$\displaystyle -4.44089209850063 \cdot 10^{-16}$ -
- -
-
-
-
- -
-
- -
- -
-
-

As python function

- -
-
-
-
- -
- -
-
- -
-
-
print( LP.L(df.X,0)(df.X[0]),LP.L(df.X,1)(df.X[1]),LP.L(df.X,2)(df.X[2]) )
-
- -
-
-
- -
-
- -
-
- -
-
0.9999999999999968 0.9999999999999951 0.9999999999999998
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
LP.L(df.X,0)(df.X)
-
- -
-
-
- -
-
- -
-
- - - -
-
0    1.000000e+00
-1   -4.440892e-16
-2    5.329071e-15
-Name: X, dtype: float64
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
LP.L(df.X,1)(df.X)
-
- -
-
-
- -
-
- -
-
- - - -
-
0   -4.302114e-16
-1    1.000000e+00
-2   -2.042810e-14
-Name: X, dtype: float64
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
LP.L(df.X,2)(df.X)
-
- -
-
-
- -
-
- -
-
- - - -
-
0    1.665335e-16
-1    0.000000e+00
-2    1.000000e+00
-Name: X, dtype: float64
-
- -
-
-
-
- -
-
- -
- -
-
-

Actividad Fit a cuatro puntos, comprobando las propiedades del polinomio de Lagrange

- -
-
-
-
- - - - -
- \ No newline at end of file diff --git a/_build/features/Minimization.html b/_build/features/Minimization.html deleted file mode 100644 index 504789b..0000000 --- a/_build/features/Minimization.html +++ /dev/null @@ -1,1873 +0,0 @@ ---- -redirect_from: - - "/features/minimization" -interact_link: content/features/Minimization.ipynb -kernel_name: python3 -kernel_path: content/features -has_widgets: false -title: |- - Minimization -pagenum: 14 -prev_page: - url: /features/interpolation_details.html -next_page: - url: /features/least_action_minimization.html -suffix: .ipynb -search: phi minimum scipy equation colab com minimization function df x hermite span action restrepo computationalmethods master material minumum org interpolation local close style global right begin mu lambda end frac plane check least pdf research google github blob ipynb src svg optimization fit optimize lectures intro html example dataset iloc degree n data finding color red values points potential div v part left point minima www href target parentimg assets badge alt open bibliography autoexamples plotoptimizeexample consider following laggrange pandas series obtain specific value using slices must note loc works recommend polynomial where corresponds second activity maximum set csv fminpowell - -comment: "***PROGRAMMATICALLY GENERATED, DO NOT EDIT. SEE ORIGINAL FILES IN /content***" ---- - -
-
Minimization
-
-
- -
-
-

Open In Colab

- -
-
-
-
- -
- -
-
-
- -
-
-
-
- -
- -
-
-

Minimization

Find the minumum of a function

-
-

Bibliography

[1] Optimization and fit scipy optimize

- - -
-
-
-
- -
- -
-
- -
-
-
%pylab inline
-
- -
-
-
- -
-
- -
-
- -
-
Populating the interactive namespace from numpy and matplotlib
-
-
-
-
-
-
- -
-
/usr/local/lib/python3.5/dist-packages/IPython/core/magics/pylab.py:160: UserWarning: pylab import has clobbered these variables: ['fmin', 'f']
-`%matplotlib` prevents importing * from pylab and numpy
-  "\n`%matplotlib` prevents importing * from pylab and numpy"
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
import numpy as np
-import scipy.optimize as optimize
-import scipy.interpolate as interpolate
-import pandas as pd
-
- -
-
-
- -
-
- -
- -
-
-

Example

-
-
-
-
- -
- -
-
-

Consider the following dataset

- -
-
-
-
- -
- -
-
- -
-
-
df=pd.DataFrame({'X':[2.5,3.1,4.5,5,5.9,6.2],
-              'Y':[3,-1.01,1.5,0.7,2.8,1.5]})
-df
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
XY
02.53.00
13.1-1.01
24.51.50
35.00.70
45.92.80
56.21.50
-
-
- -
-
-
-
- -
-
- -
- -
-
-

Laggrange interpolation

-
-
-
-
- -
- -
-
- -
-
-
pol=interpolate.lagrange(df.X,df.Y)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
print(pol)
-
- -
-
-
- -
-
- -
-
- -
-
         5         4         3         2
--0.8941 x + 19.97 x - 174.7 x + 746.7 x - 1557 x + 1264
-
-
-
-
-
-
- -
-
- -
- -
-
-

df.X is a Pandas Series

- -
-
-
-
- -
- -
-
- -
-
-
df.X
-
- -
-
-
- -
-
- -
-
- - - -
-
0    2.5
-1    3.1
-2    4.5
-3    5.0
-4    5.9
-5    6.2
-Name: X, dtype: float64
-
- -
-
-
-
- -
-
- -
- -
-
-

To obtain some specific value by using slices, we must use .iloc

-

Note that df.X[3]=df.X.loc[3]=df.X.iloc[3]

- -
-
-
-
- -
- -
-
- -
-
-
df.X[3],df.X.loc[3],df.X.iloc[3]
-
- -
-
-
- -
-
- -
-
- - - -
-
(5.0, 5.0, 5.0)
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
df.X.iloc[-1],df.X.max()
-
- -
-
-
- -
-
- -
-
- - - -
-
(6.2, 6.2)
-
- -
-
-
-
- -
-
- -
- -
-
-

works!

- -
-
-
-
- -
- -
-
- -
-
-
x=np.linspace(df.X.iloc[0],df.X.iloc[-1],100)
-plt.plot(x,pol(x))
-plt.plot(df.X,df.Y,'ro')
-plt.xlabel('X')
-plt.ylabel('Y')
-plt.grid()
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Hermite interpolation

The recommend degree for the Hermite polynomial is $n-1$ where $n$ is the number of data of the dataset

- -
-
-
-
- -
- -
-
- -
-
-
H=np.polynomial.hermite.Hermite.fit(df.X,df.Y,5)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
plt.plot(x,H(x),'k-')
-plt.plot(x,pol(x),'c--')
-plt.plot(df.X,df.Y,'ro')
-plt.grid()
-plt.xlabel('$x$')
-plt.ylabel('$H(x)$')
-
- -
-
-
- -
-
- -
-
- - - -
-
Text(0,0.5,'$H(x)$')
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Finding the local minimum of a function

-
-
-
-
- -
- -
-
-

Finding the first minimum close to 3 (which corresponds to the global minimum), and the second close to 5 (a local minimum)

- -
-
-
-
- -
- -
-
- -
-
-
min1=optimize.fmin_powell(pol,3,full_output=True)
-min2=optimize.fmin_powell(pol,5.2,full_output=True)
-
- -
-
-
- -
-
- -
-
- -
-
Optimization terminated successfully.
-         Current function value: -1.374113
-         Iterations: 2
-         Function evaluations: 28
-Optimization terminated successfully.
-         Current function value: 0.699898
-         Iterations: 2
-         Function evaluations: 50
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
min1
-
- -
-
-
- -
-
- -
-
- - - -
-
(array(2.92784955), array(-1.37411316), array([[1.]]), 2, 28, 0)
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
print('The global minimum is f(x)={} for x={};\n the local minimum is f(x)={} for x={}'.format(
-    min1[1],min1[0],min2[1],min2[0]))
-
- -
-
-
- -
-
- -
-
- -
-
The global minimum is f(x)=-1.3741131581291484 for x=2.9278495523433894;
- the local minimum is f(x)=0.6998981514389016 for x=5.004929292406532
-
-
-
-
-
-
- -
-
- -
- -
-
-

Activity Find the maximum values of the Hermite interpolation function of degree 5 to the set of points: https://github.com/restrepo/ComputationalMethods/blob/master/data/hermite.csv

- -
-
-
-
- -
- -
-
- -
-
-
df=pd.read_csv('https://raw.githubusercontent.com/restrepo/ComputationalMethods/master/data/hermite.csv')
-H=np.polynomial.hermite.Hermite.fit(df.X,df.Y,5)
-x=np.linspace(df.X.iloc[0],df.X.iloc[-1],100)
-plt.plot(x,-H(x),'k-')
-plt.grid()
-plt.xlabel('$x$')
-plt.ylabel('$H(x)$')
-
- -
-
-
- -
-
- -
-
- - - -
-
Text(0,0.5,'$H(x)$')
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

fmin_powell try to search the global minimum

- -
-
-
-
- -
- -
-
- -
-
-
optimize.fmin_powell(-H,4.5)
-
- -
-
-
- -
-
- -
-
- -
-
Optimization terminated successfully.
-         Current function value: -2.803764
-         Iterations: 2
-         Function evaluations: 27
-
-
-
-
-
-
- - - -
-
array(5.918213)
-
- -
-
-
-
- -
-
- -
- -
-
-

Find a local minumum

-
-
-
-
- -
- -
-
-

close minimum

- -
-
-
-
- -
- -
-
- -
-
-
min1=optimize.minimize(-H,x0=4.5)
-min1['x']
-
- -
-
-
- -
-
- -
-
- - - -
-
array([4.01502453])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
min1=optimize.minimize(-H,5.2)
-min1['x']
-
- -
-
-
- -
-
- -
-
- - - -
-
array([5.91821427])
-
- -
-
-
-
- -
-
- -
- -
-
-

minimum in a range

- -
-
-
-
- -
- -
-
- -
-
-
min1=optimize.minimize(-H,x0=4,bounds=((3.5, 4.5), ) )
-min1['x']
-
- -
-
-
- -
-
- -
-
- - - -
-
array([4.0150238])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
xmin_local = optimize.fminbound(-H, 3.5, 4.5)
-xmin_local
-
- -
-
-
- -
-
- -
-
- - - -
-
4.015025330027828
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
optimize.brute(-H,ranges=((3.5,4.5,0.1),))
-
- -
-
-
- -
-
- -
-
- - - -
-
array([4.01503906])
-
- -
-
-
-
- -
-
- -
- -
-
-

Find a global minumum (alternative)

-
-
-
-
- -
- -
-
- -
-
-
min1=optimize.basinhopping(-H,5.5)
-min1['x']
-
- -
-
-
- -
-
- -
-
- - - -
-
array([5.91821428])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
%pylab inline
-
- -
-
-
- -
-
- -
-
- -
-
Populating the interactive namespace from numpy and matplotlib
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
import pandas as pd
-
- -
-
-
- -
-
- -
- -
-
-

The Higgs potential

To write greek letter inside a cell use the $\rm \LaTeX$ macro and the tab, e.g: \mu<TAB>, to produce μ

- -
-
-
-
- -
- -
-
- -
-
-
α=2
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
m_H=126 # GeV/c^2 (c→1)
-G_F=1.1663787E-5 #GeV^-2
-v=1/np.sqrt(np.sqrt(2.)*G_F) # GeV
-μ=np.sqrt(m_H**2/2)
-λ=m_H**2/(2.*v**2)
-μ,λ,v
-
- -
-
-
- -
-
- -
-
- - - -
-
(89.09545442950498, 0.13093799079487806, 246.21965079413738)
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
ϕ=np.linspace(-300,300)
-Vp=lambda ϕ: 0.5*μ**2*ϕ**2+0.25*λ*ϕ**4
-plt.plot(ϕ, Vp(ϕ) )
-plt.xlabel(r'$\phi$ [GeV]',size=20 )
-plt.ylabel(r'$V(\phi)$ [GeV]',size=20)
-plt.xlabel(r'$\phi$ [GeV]',size=20 )
-plt.ylabel(r'$V(\phi)$ [GeV$^4$]',size=20)
-plt.grid()
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
μ=μ*1j
-V=lambda ϕ: Vp(ϕ).real
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
Vp(ϕ)[0].real
-
- -
-
-
- -
-
- -
-
- - - -
-
-92060568.64037189
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
ϕ=np.linspace(-380,380)
-plt.plot(ϕ, V(ϕ) )
-plt.xlabel(r'$\phi$ [GeV]',size=20 )
-plt.ylabel(r'$V(\phi)$ [GeV]',size=20)
-plt.xlabel(r'$\phi$ [GeV]',size=20 )
-plt.ylabel(r'$V(\phi)$ [GeV$^4$]',size=20)
-plt.grid()
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
fp=optimize.fmin_powell(V,200,ftol=1E-16,full_output=True)
-
- -
-
-
- -
-
- -
-
- -
-
Optimization terminated successfully.
-         Current function value: -120308559.069597
-         Iterations: 4
-         Function evaluations: 74
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
ϕ_min=fp[0]
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
print(ϕ_min,v)
-
- -
-
-
- -
-
- -
-
- -
-
246.21964987858152 246.21965079413738
-
-
-
-
-
-
- -
-
- -
- -
-
-

Minimization in higher dimensions

- -

For a complex scalar field with potential -\begin{equation} -V(\phi)=\mu^2\phi^*\phi + \lambda (\phi^*\phi)^2 -\end{equation} -with -\begin{equation} -\phi=\frac{\phi_1+i\phi_2 }{\sqrt{2} } -\end{equation} -and $\mu^2<0$, and $\lambda>0$, find some of the infinite number of minimum values of $\phi$, as illustrated in the figure, with the plane, $\phi_1-\phi_2$, moved to the minimum to easy the visualization. Expanding in terms of the real and imaginary part of $\phi$ -\begin{equation} -V(\phi)=\frac{\mu^2}{2}\left(\phi_1^2+\phi_2^2 \right) + \frac{\lambda}{4}\left( \phi_1^2+\phi_2^2\right)^2 -\end{equation}

- -
-
-
-
- -
- -
-
- -
-
-
%pylab inline
-from scipy import optimize
-import pandas as pd
-
- -
-
-
- -
-
- -
-
- -
-
Populating the interactive namespace from numpy and matplotlib
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
def f(ϕ,m_H=126,G_F=1.1663787E-5):
-    v=1/np.sqrt(np.sqrt(2.)*G_F) # GeV
-    μ=np.sqrt(m_H**2/2)*1j #imaginary mass
-    λ=m_H**2/(2.*v**2)
-    #print(μ,λ)
-    return ( 0.5*μ**2*(ϕ[0]**2+ϕ[1]**2)+0.25*λ*(ϕ[0]**2+ϕ[1]**2)**2 ).real
-
- -
-
-
- -
-
- -
- -
-
-

Check a point of the function

- -
-
-
-
- -
- -
-
- -
-
-
f([0,10])
-
- -
-
-
- -
-
- -
-
- - - -
-
-396572.6550230127
-
- -
-
-
-
- -
-
- -
- -
-
-

Check the minimim obtained when an inizialization point at $\phi_0=(0,0)$

- -
-
-
-
- -
- -
-
- -
-
-
fmin=optimize.fmin_powell(f,x0=[0,10],ftol=1E-16,full_output=True)
-fmin[0]
-
- -
-
-
- -
-
- -
-
- -
-
Optimization terminated successfully.
-         Current function value: -120308559.069597
-         Iterations: 3
-         Function evaluations: 111
-
-
-
-
-
-
- - - -
-
array([246.21914011,  -0.50137284])
-
- -
-
-
-
- -
-
- -
- -
-
-

Check the proyection of the minimum in the plane $\phi_1-\phi_2$

- -
-
-
-
- -
- -
-
- -
-
-
print('V(ϕ)={} GeV^4'.format(fmin[1].round(1)))
-
- -
-
-
- -
-
- -
-
- -
-
V(ϕ)=-120308559.1 GeV^4
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
np.sqrt( fmin[0][0]**2+fmin[0][1]**2 )
-
- -
-
-
- -
-
- -
-
- - - -
-
246.21965057683713
-
- -
-
-
-
- -
-
- -
- -
-
-

For random initialization points, we can get several minima

- -
-
-
-
- -
- -
-
- -
-
-
np.random.uniform(-300,300,2)
-
- -
-
-
- -
-
- -
-
- - - -
-
array([-164.99567257,  -65.7636795 ])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
df=pd.DataFrame()
-for i in range(1000):
-    ϕ0=np.random.uniform(-300,300,2)
-    ϕmin=optimize.fmin_powell(f,x0=ϕ0,ftol=1E-16,disp=False)
-    df=df.append({'ϕ1':ϕmin[0],'ϕ2':ϕmin[1]},ignore_index=True)
-
- -
-
-
- -
-
- -
- -
-
-

Projection of the minima in the plane, $\phi_1,\phi_2$

- -
-
-
-
- -
- -
-
- -
-
-
df[:3]
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
ϕ1ϕ2
0118.814666-215.655260
1239.086165-58.838100
2228.276742-92.270501
-
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
plt.figure( figsize=(6,6) )
-plt.plot(df['ϕ1'],df['ϕ2'],'r.',label=r'$\phi_{{\rm min}}={}$ GeV'.format(
-    np.sqrt(df.loc[0,'ϕ1']**2+df.loc[0,'ϕ2']**2).round(1)))
-plt.plot(df.loc[0,'ϕ1'],df.loc[0,'ϕ2'],'k*',label='Our Universe',markersize=10)
-plt.xlabel('$\phi_1$',size=15)
-plt.ylabel('$\phi_2$',size=15)
-plt.legend(loc='best')
-plt.grid()
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Least action

See Least action minimization

- -
-
-
-
- - - - - - -
- \ No newline at end of file diff --git a/_build/features/Pandas.html b/_build/features/Pandas.html deleted file mode 100644 index 4346f77..0000000 --- a/_build/features/Pandas.html +++ /dev/null @@ -1,5786 +0,0 @@ ---- -redirect_from: - - "/features/pandas" -interact_link: content/features/Pandas.ipynb -kernel_name: python3 -kernel_path: content/features -has_widgets: false -title: |- - Data analysis with Pandas -pagenum: 3 -prev_page: - url: /features/scientific-libraries.html -next_page: - url: /features/matplotlib.html -suffix: .ipynb -search: pandas data dataframe com dictionary series web file python analysis list github dictionaries open used lists column restrepo excel spreadsheet key example json colab google relational just keys activity apply level also structures even row function master any already machine similar odd previous resulting format databases string authors research blob ipynb org flexible labeled world goal pbpython drive png load structure new rows columns before dataframes df cell index same values instead img obtain quotes computationalmethods material docs easy real html numpy based dimensional corresponds indices programming creating main check formats link specific value note methods double microsoft option not - -comment: "***PROGRAMMATICALLY GENERATED, DO NOT EDIT. SEE ORIGINAL FILES IN /content***" ---- - -
-
Data analysis with Pandas
-
-
- -
-
-

Open In Colab

- -
-
-
-
- -
- -
-
-

Pandas

Open In Colab

- -
-
-
-
- -
- -
-
-

From http://pandas.pydata.org/pandas-docs/stable/

-

pandas is a Python package providing fast, flexible, and expressive data structures designed to make working with “relational” or “labeled” data both easy and intuitive. It aims to be the fundamental high-level building block for doing practical, real world data analysis in Python. Additionally, it has the broader goal of becoming the most powerful and flexible open source data analysis / manipulation tool available in any language. It is already well on its way toward this goal.

-

See also:

- - -
-
-
-
- -
- -
-
-

A good and practice book about Pandas possibilities is:

-

Python for Data Analysis
-Data Wrangling with Pandas, NumPy, and IPython
-By William McKinney

-

This other is about aplications based on Pandas: -image.png Introduction to Machine Learning with Python
-A Guide for Data Scientists -By Sarah Guido, Andreas Müller

-

Pandas can be used in a similar way to R, which is based on similar data structures. Pandas also can replace the use of graphical interfaces to access spreadsheets like Excel

- -
-
-
-
- -
- -
-
-

Standard way to load the module

-
-
-
-
- -
- -
-
- -
-
-
import pandas as pd
-
- -
-
-
- -
-
- -
- -
-
-

Basic structure: DataFrame

-
-
-
-
- -
- -
-
-

An flat spreadsheet can be seen in terms of the types of variables of Python just as dictionary of lists, where each column of the spreadsheet is a pair key-list of the dictionary

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
AB
1evenodd
201
323
445
567
689
- -
-
-
-
- -
- -
-
- -
-
-
numbers={"even": [0,2,4,6,8],   #  First  key-list
-         "odd" : [1,3,5,7,9] }  #  Second key-list
-
- -
-
-
- -
-
- -
- -
-
-

Data structures

-
-
-
-
- -
- -
-
-

Pandas has two new data structures:

-
    -
  1. DataFrame which are similar to numpy arrays but with some assigned key. For example, for the previous case
    import numpy as np
    -np.array([[0,1],
    -       [2,3],
    -       [4,5],
    -       [6,7],
    -       [8,9] 
    -      ])
    -
    -
  2. -
  3. Series which are enriched to dictionaries, as the ones defined for the rows of the previous example: {'even':0,'odd':1}.
  4. -
- -
-
-
-
- -
- -
-
-

The rows in a two-dimensional DataFrame corresponds to Series with similar keys, while the columns are also Series with the indices as keys.

-

An example of a DataFrame is a spreadsheet, as the one before.

- -
-
-
-
- -
- -
-
-

DataFrame

Pandas can convert a dictionary of lists, like the numbers dictionary before, into a DataFrame, which is just an spreadsheet but interpreted at the programming level:

- -
-
-
-
- -
- -
-
- -
-
-
numbers
-
- -
-
-
- -
-
- -
-
- - - -
-
{'even': [0, 2, 4, 6, 8], 'odd': [1, 3, 5, 7, 9]}
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
import pandas as pd
-df=pd.DataFrame(numbers)
-df
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
evenodd
001
123
245
367
489
-
-
- -
-
-
-
- -
-
- -
- -
-
-

It is equivalent to:

- -
-
-
-
- -
- -
-
- -
-
-
df.to_dict()
-
- -
-
-
- -
-
- -
-
- - - -
-
{'even': {0: 0, 1: 2, 2: 4, 3: 6, 4: 8}, 'odd': {0: 1, 1: 3, 2: 5, 3: 7, 4: 9}}
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
pd.DataFrame(  {'even': {0: 0, 1: 2, 2: 4, 3: 6, 4: 8}, 'odd': {0: 1, 1: 3, 2: 5, 3: 7, 4: 9}} )
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
evenodd
001
123
245
367
489
-
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
pd.DataFrame.from_dict(numbers)
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
evenodd
001
123
245
367
489
-
-
- -
-
-
-
- -
-
- -
- -
-
-

See below for other possibilities of creating Pandas DataFrames from lists and dictionaries

- -
-
-
-
- -
- -
-
-

The main advantage of the DataFrame, df, is that it can be managed without a graphical interface.

- -
-
-
-
- -
- -
-
-

We can check the shape of the DataFrame

- -
-
-
-
- -
- -
-
- -
-
-
df.shape
-
- -
-
-
- -
-
- -
-
- - - -
-
(5, 2)
-
- -
-
-
-
- -
-
- -
- -
-
-

Export DataFrame to other formats

    -
  • To export to excel:
  • -
- -
-
-
-
- -
- -
-
- -
-
-
df.to_excel('example.xlsx',index=False)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
newdf=pd.read_excel('example.xlsx')
-newdf
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
evenodd
001
123
245
367
489
-
-
- -
-
-
-
- -
-
- -
- -
-
-

Activity: Open the resulting spreadsheet in Google Drive, publish it and open from the resulting link with Pandas in the next cell

- -
-
-
-
- -
- -
-
- -
-
-
df=pd.read_excel('PASTE THE PUBLISHED LINK HERE')
-df
-
- -
-
-
- -
-
- -
- -
-
-

Series

-
-
-
-
- -
- -
-
-

Each column of the DataFrame is now an augmented dictionary called Series, with the indices as the keys of the Series

- -
-
-
-
- -
- -
-
-

A Pandas Series object can be just initialized from a Python dictionary:

- -
-
-
-
- -
- -
-
- -
-
-
type( df['even'] )
-
- -
-
-
- -
-
- -
-
- - - -
-
pandas.core.series.Series
-
- -
-
-
-
- -
-
- -
- -
-
-

The keys are the index of the DataFrame

- -
-
-
-
- -
- -
-
- -
-
-
#df['even']
-df.even[4]
-
- -
-
-
- -
-
- -
-
- - - -
-
8
-
- -
-
-
-
- -
-
- -
- -
-
-

Each row is also a series

- -
-
-
-
- -
- -
-
- -
-
-
df.loc[0]
-
- -
-
-
- -
-
- -
-
- - - -
-
even    0
-odd     1
-Name: 0, dtype: int64
-
- -
-
-
-
- -
-
- -
- -
-
-

with keys: 'even' and 'odd'

- -
-
-
-
- -
- -
-
- -
-
-
df.loc[0]['even']
-
- -
-
-
- -
-
- -
-
- - - -
-
0
-
- -
-
-
-
- -
-
- -
- -
-
-

or attributes even and odd

- -
-
-
-
- -
- -
-
- -
-
-
df.loc[0].odd
-
- -
-
-
- -
-
- -
-
- - - -
-
1
-
- -
-
-
-
- -
-
- -
- -
-
-

One specific cell value can be reached with the index and the key:

- -
-
-
-
- -
- -
-
- -
-
-
df.loc[2,'odd']
-
- -
-
-
- -
-
- -
-
- - - -
-
5
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
s=pd.Series({'Name':'Juan Valdez','Nacionality':'Colombia','Age':23})
-s
-
- -
-
-
- -
-
- -
-
- - - -
-
Name           Juan Valdez
-Nacionality       Colombia
-Age                     23
-dtype: object
-
- -
-
-
-
- -
-
- -
- -
-
-

Note that the key name can be used also as an attribute.

- -
-
-
-
- -
- -
-
- -
-
-
df.odd
-
- -
-
-
- -
-
- -
-
- - - -
-
0    1
-1    3
-2    5
-3    7
-4    9
-Name: odd, dtype: int64
-
- -
-
-
-
- -
-
- -
- -
-
-

The power of Pandas rely in that their main data structures: DataFrames and Series, are enriched with many useful methods and attributes.

-
-

Official definition of Pandas

Pandas is a Python package providing fast, flexible, and expressive data structures designed to make working with “relational” or “labeled” data both easy and intuitive. It aims to be the fundamental high-level building block for doing practical, real world data analysis in Python. Additionally, it has the broader goal of becoming the most powerful and flexible open source data analysis / manipulation tool available in any language. It is already well on its way toward this goal.

-
-
    -
  • "relational": the list of data is identified with some unique index (like a SQL table)
  • -
  • "labeled": the list is identified with a key, like the previous odd or even keys.
  • -
- -
-
-
-
- -
- -
-
-

For example. A double bracket [[...]], can be used to filter data.

-

A row in a two-dimensional DataFrame corresponds to Series with the same keys of the DataFrame, but with single values instead of a list

- -
-
-
-
- -
- -
-
- -
-
-
df.loc[[0]]
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - -
evenodd
001
-
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
print( 'the row has' )
-print( '                  keys: {} and values: {}'.format( list( df.loc[[0]].keys() ),df.loc[[0]].values[0]  ) )
-print( "like the dictionay:" )
-print( "                      { 'even' : 0, 'odd' : 1 }")
-
- -
-
-
- -
-
- -
-
- -
-
the row has
-                  keys: ['even', 'odd'] and values: [0 1]
-like the dictionay:
-                      { 'even' : 0, 'odd' : 1 }
-
-
-
-
-
-
- -
-
- -
- -
-
-

To filter a column:

- -
-
-
-
- -
- -
-
- -
-
-
df[['odd']]
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
odd
01
13
25
37
49
-
-
- -
-
-
-
- -
-
- -
- -
-
-

More on Series

-
-
-
-
- -
- -
-
-

A Pandas Series object can be just initialized from a Python dictionary:

- -
-
-
-
- -
- -
-
- -
-
-
s=pd.Series({'Name':'Juan Valdez','Nacionality':'Colombia','Age':23})
-s
-
- -
-
-
- -
-
- -
-
- - - -
-
Name           Juan Valdez
-Nacionality       Colombia
-Age                     23
-dtype: object
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
s['Name']
-
- -
-
-
- -
-
- -
-
- - - -
-
'Juan Valdez'
-
- -
-
-
-
- -
-
- -
- -
-
-

but also as containers of name spaces!

- -
-
-
-
- -
- -
-
- -
-
-
s.Name
-
- -
-
-
- -
-
- -
-
- - - -
-
'Juan Valdez'
-
- -
-
-
-
- -
-
- -
- -
-
-

DataFrame initialization

-
-
-
-
- -
- -
-
-

Initization from an existing spreadsheet.

This can be locally in your computer o from some downloadable link

- -
-
-
-
- -
- -
-
- -
-
-
df=pd.read_excel('http://bit.ly/spreadsheet_xlsx')
-df
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
NombreEdadCompañia
0Juan Valdez23Café de Colombia
1Álvaro Uribe Vélez65Senado de la República
-
-
- -
-
-
-
- -
-
- -
- -
-
-

To make a downloadable link for any spread sheet in Google Drive, follow the sequence:

- -
File → Publish to the web...→ Entire Document → Web page → Microsoft excel (xlsx)
-

as illustrated in the figure: -GS

- -
-
-
-
- -
- -
-
- -
-
-
df.loc[0,'Edad']=32
-#df.at[0,'Edad']=32
-df
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
NombreEdadCompañia
0Juan Valdez32Café de Colombia
1Álvaro Uribe Vélez65Senado de la República
-
-
- -
-
-
-
- -
-
- -
- -
-
-

After some modification

- -
-
-
-
- -
- -
-
-

it can be saved again as an excel file with the option to not create a column of indices: index=False

- -
-
-
-
- -
- -
-
-

Intialization from lists and dictionaries

-
-
-
-
- -
- -
-
-

Inizialization from Series

We start with an empty DataFrame:

- -
-
-
-
- -
- -
-
-

Creating Pandas DataFrame from list and dictionaries offers many alternatives

-

creating dataframes

-

Row oriented way

- -
-
-
-
- -
- -
-
- -
-
-
pd.DataFrame({'Nombre'   : ['Juan Valdez','Álvaro Uribe Vélez'],
-              'Edad'     : [32,            65                 ],
-              'Compañia' : ['Café de Colombia','Senado de la República']})
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
NombreEdadCompañia
0Juan Valdez32Café de Colombia
1Álvaro Uribe Vélez65Senado de la República
-
-
- -
-
-
-
- -
-
- -
- -
-
-
    -
  • We can obtain the DataFrame from list of items
  • -
- -
-
-
-
- -
- -
-
- -
-
-
pd.DataFrame.from_items([ [ 'Nombre'  , ['Juan Valdez','Álvaro Uribe Vélez']],
-                          [ 'Edad'    , [  32,            65               ]],
-                          [ 'Compañia', ['Café de Colombia','Senado de la República']] ])
-
- -
-
-
- -
-
- -
- -
-
-
    -
  • We can obtain the DataFrame from dictionary
  • -
- -
-
-
-
- -
- -
-
- -
-
-
pd.DataFrame( [{'Nombre':'Juan Valdez',        'Edad': 32   ,'Compañia':'Café de Colombia'      },
-              {'Nombre':'Álvaro Uribe Vélez', 'Edad': 65   ,'Compañia':'Senado de la República'}]
-            )
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
CompañiaEdadNombre
0Café de Colombia32Juan Valdez
1Senado de la República65Álvaro Uribe Vélez
-
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
df=pd.DataFrame()
-df
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - -
-
-
- -
-
-
-
- -
-
- -
- -
-
-

Initialization from sequential rows as Series

We start with an empty DataFrame:

- -
-
-
-
- -
- -
-
- -
-
-
df=pd.DataFrame()
-df.empty
-
- -
-
-
- -
-
- -
-
- - - -
-
True
-
- -
-
-
-
- -
-
- -
- -
-
-

We can append a dictionary (or Series) as a row of the DataFrame, provided that we always use the option: ignore_index=True

- -
-
-
-
- -
- -
-
- -
-
-
d={'Name':'Juan Valdez','Nacionality':'Colombia','Age':23}
-df=df.append(d,ignore_index=True)
-df
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - -
AgeNacionalityName
023.0ColombiaJuan Valdez
-
-
- -
-
-
-
- -
-
- -
- -
-
-

We can fix the type of data of the 'Age' column

- -
-
-
-
- -
- -
-
- -
-
-
type(df.Age[0])
-
- -
-
-
- -
-
- -
-
- - - -
-
numpy.float64
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
df['Age']=df.Age.astype(int)
-df
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - -
AgeNacionalityName
023ColombiaJuan Valdez
-
-
- -
-
-
-
- -
-
- -
- -
-
-

To add a second file we build another dict

- -
-
-
-
- -
- -
-
- -
-
-
d={}
-for k in ['Name','Nacionality','Age','Company']:
-    var=input('{}:\n'.format(k))
-    d[k]=var
-
- -
-
-
- -
-
- -
-
- -
-
Name:
-Diego Restrepo
-Nacionality:
-Colombia
-Age:
-33
-Company:
-Universidad de Antioquia
-
-
-
-
-
-
- -
-
- -
- -
-
-

Exercises

    -
  • Display the resulting Series in the screen:
  • -
- -
-
-
-
- -
- -
-
-
    -
  • Append to the previous DataFrame and visualize it:
  • -
- -
-
-
-
- -
- -
-
- -
-
-
df=df.append(d,ignore_index=True)
-df
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
AgeNacionalityNameCompany
023ColombiaJuan ValdezNaN
133ColombiaDiego RestrepoUniversidad de Antioquia
-
-
- -
-
-
-
- -
-
- -
- -
-
-
    -
  • Fill NaN with empty strings
  • -
- -
-
-
-
- -
- -
-
- -
-
-
df=df.fillna('')
-
- -
-
-
- -
-
- -
- -
-
-
    -
  • Save Pandas DataFrame as an Excel file
  • -
- -
-
-
-
- -
- -
-
- -
-
-
df.to_excel('prof.xlsx',index=False)
-
- -
-
-
- -
-
- -
- -
-
-
    -
  • Load pandas DataFrame from the saved file in Excel
  • -
- -
-
-
-
- -
- -
-
- -
-
-
pd.read_excel('prof.xlsx')
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
AgeNacionalityNameCompany
023ColombiaJuan ValdezNaN
133ColombiaDiego RestrepoUniversidad de Antioquia
-
-
- -
-
-
-
- -
-
- -
- -
-
-

Common operations upon DataFrames

See https://github.com/restrepo/PythonTipsAndTricks

- -
-
-
-
- -
- -
-
-
    -
  • To fill a specific cell
  • -
- -
-
-
-
- -
- -
-
- -
-
-
df.at[0,'Company']='Federación de Caferos'
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
df
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
AgeNacionalityNameCompany
023ColombiaJuan ValdezFederación de Caferos
133ColombiaDiego RestrepoUniversidad de Antioquia
-
-
- -
-
-
-
- -
-
- -
- -
-
-

Other formats to saving and read files

We are interested in format which keeps the tags of the columns, like 'Nombre', 'Edad', 'Compañia'

- -
-
-
-
- -
- -
-
- -
-
-
df=pd.read_excel('http://bit.ly/spreadsheet_xlsx')
-df
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
NombreEdadCompañia
0Juan Valdez23Café de Colombia
1Álvaro Uribe Vélez65Senado de la República
-
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
type(df.loc[0,'Edad'])
-
- -
-
-
- -
-
- -
-
- - - -
-
numpy.int64
-
- -
-
-
-
- -
-
- -
- -
-
-

CSV

-
-
-
-
- -
- -
-
- -
-
-
df.to_csv('hoja.csv',index=False)
-
- -
-
-
- -
-
- -
- -
-
-

We can check the explicit file format with

- -
-
-
-
- -
- -
-
- -
-
-
df.to_csv(None,index=False)
-
- -
-
-
- -
-
- -
-
- - - -
-
'Nombre,Edad,Compañia\nJuan Valdez,23,Café de Colombia\nÁlvaro Uribe Vélez,65,Senado de la República\n'
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
print(df.to_csv(None,index=False))
-
- -
-
-
- -
-
- -
-
- -
-
Nombre,Edad,Compañia
-Juan Valdez,23,Café de Colombia
-Álvaro Uribe Vélez,65,Senado de la República
-
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
pd.read_csv('hoja.csv')
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
NombreEdadCompañia
0Juan Valdez23Café de Colombia
1Álvaro Uribe Vélez65Senado de la República
-
-
- -
-
-
-
- -
-
- -
- -
-
-

JSON

-
-
-
-
- -
- -
-
-

This format keeps the Python lists and dictionaries at the storage level

- -
-
-
-
- -
- -
-
- -
-
-
df=pd.DataFrame([{"Name":"Donald Trump","Age":74},
-                 {"Name":"Barak Obama", "Age":59}])
-df
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - -
NameAge
0Donald Trump74
1Barak Obama59
-
-
- -
-
-
-
- -
-
- -
- -
-
-

This format allow us to keep exactly the very same list of dictionaries structure!

- -
-
-
-
- -
- -
-
- -
-
-
print(df.to_json(None,orient='records'))
-
- -
-
-
- -
-
- -
-
- -
-
[{"Name":"Donald Trump","Age":74},{"Name":"Barak Obama","Age":59}]
-
-
-
-
-
-
- -
-
- -
- -
-
-

Activity:

-
    -
  • Save to a file instead of None and open the file with some editor.
  • -
- -
-
-
-
- -
- -
-
- -
-
-
df.to_json('presidents.json',orient='records')
-
- -
-
-
- -
-
- -
- -
-
-
    -
  • Add a break-line at the end of the first dictionary and try to -load the resulting file with pd.read_json
  • -
- -
-
-
-
- -
- -
-
- -
-
-
pd.read_json('presidents.json')
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - -
NameAge
0Donald Trump74
1Barak Obama59
-
-
- -
-
-
-
- -
-
- -
- -
-
-

JSON allows for some flexibility in the break-lines structure:

- -
-
-
-
- -
- -
-
- -
-
-
hm='''
-hola
-mundo
-'''
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
hm
-
- -
-
-
- -
-
- -
-
- - - -
-
'\nhola\nmundo\n'
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
pd.read_json('''
-             [{"Name":"Donald Trump","Age":73},
-              {"Name":"Barak Obama", "Age":58}]
-            ''')
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - -
NameAge
0Donald Trump73
1Barak Obama58
-
-
- -
-
-
-
- -
-
- -
- -
-
-

For large databases it is convinient just to accumulate dictionaries in a sequential form:

- -
-
-
-
- -
- -
-
- -
-
-
print(df.to_json(None,orient='records',lines=True))
-
- -
-
-
- -
-
- -
-
- -
-
{"Name":"Donald Trump","Age":74}
-{"Name":"Barak Obama","Age":59}
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
pd.read_json('''
-             {"Name":"Donald Trump","Age":73}
-             {"Name":"Barak Obama", "Age":58}
-            ''',orient='records',lines=True)
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - -
NameAge
0Donald Trump73
1Barak Obama58
-
-
- -
-
-
-
- -
-
- -
- -
-
-

Activity:

-
    -
  • Save to a file instead of None, with options: orient='records',lines=True, and open the file with some editor.
  • -
- -
-
-
-
- -
- -
-
- -
-
-
df.to_json('presidents.json',orient='records',lines=True)
-
- -
-
-
- -
-
- -
- -
-
-
    -
  • Add a similar dictionary in the next new line, and try to -load the resulting file with pd.read_json with options: orient='records',lines=True.
      -
    • WARNING: Use doble-quotes " to write the keys od the new -dictionary
    • -
    -
  • -
- -
-
-
-
- -
- -
-
-

Any Python string need to be converted first to double-quotes before to be used as JSON string.

-

Example

- -
-
-
-
- -
- -
-
- -
-
-
numbers={"even": [0,2,4,-6,8],   #  First  key-list
-         "odd" : [1,3,-5,7,9] }  #  Second key-list
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
numbers
-
- -
-
-
- -
-
- -
-
- - - -
-
{'even': [0, 2, 4, -6, 8], 'odd': [1, 3, -5, 7, 9]}
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
str(numbers)
-
- -
-
-
- -
-
- -
-
- - - -
-
"{'even': [0, 2, 4, -6, 8], 'odd': [1, 3, -5, 7, 9]}"
-
- -
-
-
-
- -
-
- -
- -
-
-

This string can be writing in the JSON format by replacing the single quotes, ' , by duoble quotes, ":

- -
-
-
-
- -
- -
-
- -
-
-
str(numbers).replace("'",'"')
-
- -
-
-
- -
-
- -
-
- - - -
-
'{"even": [0, 2, 4, -6, 8], "odd": [1, 3, -5, 7, 9]}'
-
- -
-
-
-
- -
-
- -
- -
-
-

and now can be used as an JSON input

- -
-
-
-
- -
- -
-
- -
-
-
df=pd.read_json(  str(numbers).replace("'",'"') )
-df
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
evenodd
001
123
24-5
3-67
489
-
-
- -
-
-
-
- -
-
- -
- -
-
-

Activity: Try to read the string as JSON without make the double-quote replacement

- -
-
-
-
- -
- -
-
-

Filters

The main application of labeled data for data analysis is the possibility to make filers, or cuts, to obtain specific reduced datasets to further analysis

- -
-
-
-
- -
- -
-
- -
-
-
df
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
evenodd
001
123
24-5
3-67
489
-
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
df[df.even.abs()>4]
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - -
evenodd
3-67
489
-
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#and
-df[(df.even>0) & (df.odd<0)]
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - -
evenodd
24-5
-
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
df[~((df.even>0) & (df.odd<0)) ]
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
evenodd
001
123
3-67
489
-
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#or
-df[(df.even<0) | (df.odd<0)]
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - -
evenodd
24-5
3-67
-
-
- -
-
-
-
- -
-
- -
- -
-
-

The apply method

The advantage of the spreadsheet paradigm is that the columns can be transformed with functions. All the typical functions avalaible for a spreadsheet are already implemented like the method .abs() used before, or the method: .sum()

- -
-
-
-
- -
- -
-
- -
-
-
df.even.sum()
-
- -
-
-
- -
-
- -
-
- - - -
-
8
-
- -
-
-
-
- -
-
- -
- -
-
-

Activity: Explore the avalaible methods by using the completion system of the notebook after the last semicolon of df.even.

- -
-
-
-
- -
- -
-
-

In addittion, for the DataFrame paradigm, we can easy implement any other function directly at the programming level either along the columns or along the rows

- -
-
-
-
- -
- -
-
-

Column-level apply

We just select the column and apply the direct or implicit function:

-
    -
  • Pre-defined function
  • -
- -
-
-
-
- -
- -
-
- -
-
-
df.even.apply(abs)
-
- -
-
-
- -
-
- -
-
- - - -
-
0    0
-1    2
-2    4
-3    6
-4    8
-Name: even, dtype: int64
-
- -
-
-
-
- -
-
- -
- -
-
-
    -
  • Implicit function
  • -
- -
-
-
-
- -
- -
-
- -
-
-
df.even.apply(lambda n:isinstance(n,int))
-
- -
-
-
- -
-
- -
-
- - - -
-
0    True
-1    True
-2    True
-3    True
-4    True
-Name: even, dtype: bool
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
df.even.apply(lambda n: n**2)
-
- -
-
-
- -
-
- -
-
- - - -
-
0     0
-1     4
-2    16
-3    36
-4    64
-Name: even, dtype: int64
-
- -
-
-
-
- -
-
- -
- -
-
-

Row-level apply

The foll row is passed as dictionary to the explicit or implicit function when apply is used for the full DataFrame and the option axis=1 is used at the end

- -
-
-
-
- -
- -
-
- -
-
-
df['even']+df['odd']
-
- -
-
-
- -
-
- -
-
- - - -
-
0     1
-1     5
-2    -1
-3     1
-4    17
-dtype: int64
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
df.apply(lambda row: row['even']+row['odd']**2,axis='columns')
-
- -
-
-
- -
-
- -
-
- - - -
-
0     1
-1    11
-2    29
-3    43
-4    89
-dtype: int64
-
- -
-
-
-
- -
-
- -
- -
-
-

Chain tools for data analysis

There are several chain tools for data analyis like the

-
    -
  • Spreadsheet based one, like Excel
  • -
  • Relational databases with the use of more advanced SQL tabular data with some data base software like MySQL
  • -
  • Non-relational databases with Pandas, R, or MongoDB
  • -
-

Here we illustrate an example of use fo a non-relational database with Pandas

- -
-
-
-
- -
- -
-
-

Relational databases

-
-
-
-
- -
- -
-
- -
-
-
df=pd.read_excel('http://bit.ly/spreadsheet_xlsx')
-persona=df[['Nombre','Edad']]
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
persona['id']=[888,666]
-persona
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
NombreEdadid
0Juan Valdez23888
1Álvaro Uribe Vélez65666
-
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
d1={'id':888, 'Inicio':2010,'Fin:':None,'Cargo':'Arriero','Compañía':'Café de Colombia'}
-d2={'id':666, 'Inicio':2013,'Fin:':2020,'Cargo':'Senador','Compañía':'Senado de la República de Colombia'}
-d3={'id':666, 'Inicio':2020,'Fin:':None,'Cargo':'Influencer','Compañía':'Twitter'}
-trabajo=pd.DataFrame( [d1,d2,d3] )  
-trabajo
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
idInicioFin:CargoCompañía
08882010NaNArrieroCafé de Colombia
166620132020.0SenadorSenado de la República de Colombia
26662020NaNInfluencerTwitter
-
-
- -
-
-
-
- -
-
- -
- -
-
-

img

- -
-
-
-
- -
- -
-
-

Actividad

Obtenga el último trabajo de Álvaro Uribe Vélez

- -
-
-
-
- -
- -
-
- -
-
-
cc=persona[persona['Nombre'].str.lower().str.contains('álvaro uribe vélez')].iloc[0].get('id')
-trabajo[trabajo['id']==cc]['Cargo'].iloc[-1]
-
- -
-
-
- -
-
- -
-
- - - -
-
'Influencer'
-
- -
-
-
-
- -
-
- -
- -
-
-

Non-relational databases

-
-
-
-
- -
- -
-
- -
-
-
persona=persona.drop('id',axis='columns')
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
persona['Trabajo']=''
-#Column need to be converted to object to assign an advance object like a list
-persona['Trabajo']=persona['Trabajo'].astype('object')
-persona.at[0,'Trabajo']=[d1]
-persona.at[1,'Trabajo']=[d2,d3]
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
persona
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
NombreEdadTrabajo
0Juan Valdez23[{'id': 888, 'Inicio': 2010, 'Fin:': None, 'Cargo': 'Arriero', 'Compañía': 'Café de Colombia'}]
1Álvaro Uribe Vélez65[{'id': 666, 'Inicio': 2013, 'Fin:': 2020, 'Cargo': 'Senador', 'Compañía': 'Senado de la República de Colombia'}, {'id': 666, 'Inicio': 2020, 'Fin:': None, 'Cargo': 'Influencer', 'Compañía': 'Twit...
-
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
pd.DataFrame( persona.loc[1,'Trabajo'] )
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
idInicioFin:CargoCompañía
066620132020.0SenadorSenado de la República de Colombia
16662020NaNInfluencerTwitter
-
-
- -
-
-
-
- -
-
- -
- -
-
-

Actividad

Obtenga el último trabajo de Álvaro Uribe Vélez

- -
-
-
-
- -
- -
-
- -
-
-
persona[persona['Nombre']=='Álvaro Uribe Vélez'
-       ].Trabajo.apply(
-        lambda l: [d.get('Cargo') for d in l ]).str[-1]
-
- -
-
-
- -
-
- -
-
- - - -
-
1    Influencer
-Name: Trabajo, dtype: object
-
- -
-
-
-
- -
-
- -
- -
-
-

We have shown that the simple two dimensional spreadsheets where each cell values is a simple type like string, integer, or float, can be represented as a dictionary of lists values or a list of dictionary column-value assignment.

-

We can go further and allow to store in the value itself a more general data structure, like nested lists and dictionaries. This allows advanced data-analysis when the apply methos is used to operate inside the nested lists or dictionaries.

-

See for example:

- -
-
-
-
- -
- -
-
-

World wide web

There are really three kinds of web

-
    -
  • The normal web,
  • -
  • The deep web,
  • -
  • The machine web. The web for machine readable responses. It is served in JSON or XML formats, which preserve programming objects.
  • -
- -
-
-
-
- -
- -
-
-

Normal web

-
-
-
-
- -
- -
-
- -
-
-
pd.read_html('https://en.wikipedia.org/wiki/COVID-19_pandemic_by_country_and_territory')[0][1:]
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
COVID-19 pandemicCOVID-19 pandemic.1
1DiseaseCOVID-19
2Virus strainSARS-CoV-2
3SourceProbably bats, possibly via pangolins[1][2]
4LocationWorldwide
5First outbreakMainland China[3]
6Index caseWuhan, Hubei, China.mw-parser-output .geo-default,.mw-parser-output .geo-dms,.mw-parser-output .geo-dec{display:inline}.mw-parser-output .geo-nondefault,.mw-parser-output .geo-multi-punct{display:...
7Date1 December 2019[3] – present(1 year, 3 months, 3 weeks and 3 days)
8Confirmed cases124,971,776[4]
9Active cases51,331,455[4]
10Recovered70,893,740[4]
11Deaths2,746,581[4]
12Territories192[4]
-
-
- -
-
-
-
- -
-
- -
- -
-
-

Real world example: microsoft academics -img

- -
-
-
-
- -
- -
-
-

Machine web

For example, consider the following normal web page:

-

http://old.inspirehep.net/search?p=doi:10.1103/PhysRevLett.122.132001

-

about a Scientific paper with people from the University of Antioquia. A machine web version can be easily obtained in JSON just by attaching the extra parameter &of=recjson, and direcly loaded from Pandas, which works like a browser for the third web:

- -
-
-
-
- -
- -
-
- -
-
-
import pandas as pd
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
df=pd.read_json('http://old.inspirehep.net/search?p=doi:10.1103/PhysRevLett.122.132001&of=recjson')
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
df
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commentreferenceabstractcreation_dateimprintprimary_report_numberkeywordspublication_infocoyrightsubject...number_of_authorslicenseaccelerator_experimentnumber_of_commentsurlrecidcollectionthesaurus_termsfiletypesprepublication
0Submitted to Phys. Rev. Lett. All figures and tables can be found at http://cms-results.web.cern.ch/cms-results/public-results/publications/BPH-18-007 (CMS Public Pages). This version corrects the...[{'title': 'Phys.Rev.Lett.,81,2432', 'year': '1998', 'doi': 'doi:10.1103/PhysRevLett.81.2432', 'order_number': '1', 'authors': 'F. Abe'}, {'title': 'Phys.Rev.,D49,5845', 'year': '1994', 'doi': 'do...[{'number': 'arXiv', 'summary': 'Signals consistent with the B$^+_\mathrm{c}$(2S) and B$^{*+}_\mathrm{c}$(2S) states are observed in proton-proton collisions at $\sqrt{s} =$ 13 TeV, in an event sa...2019-02-05T04:03:36{'date': '2019-04-03'}[arXiv:1902.00571, None, CMS-BPH-18-007, CERN-EP-2019-014][{'institute': 'publisher', 'term': 'Elementary Particles and Fields'}]{'volume': '122', 'pagination': '132001', 'title': 'Phys.Rev.Lett.', 'year': '2019'}{'date': '2019', 'holder_contact': 'publication', 'holder': 'CERN'}[{'source': 'INSPIRE', 'term': 'Experiment-HEP'}, {'source': 'arXiv', 'term': 'hep-ex'}, {'source': 'INSPIRE', 'term': 'Experiment-HEP'}]...2279[{'url': 'http://creativecommons.org/licenses/by/4.0/', 'material': 'preprint', 'license': 'CC BY 4.0'}, {'imposing': 'APS', 'url': 'https://creativecommons.org/licenses/by/4.0/', 'license': 'Crea...{'experiment': 'CERN-LHC-CMS'}0[{'url': 'http://inspirehep.net/record/1718338/files/Figure_001.png', 'description': '00002 Transitions between the lightest \BC states, with solid and dashed lines indicating the emission of phot...1718338[{'primary': 'HEP'}, {'primary': 'Citeable'}, {'primary': 'CORE'}, {'primary': 'Fermilab'}, {'primary': 'Published'}][{'term': 'p p: scattering'}, {'term': 'p p: colliding beams'}, {'term': 'B/c+: hadroproduction'}, {'term': 'B/c: excited state'}, {'term': 'B/c+: hadronic decay'}, {'term': 'excited state: hadron...[xml, pdf, pdf, pdf, png, png, png]{'date': '2019-02-01'}
-

1 rows × 36 columns

-
-
- -
-
-
-
- -
-
- -
- -
-
-

We can see that the column authors is quite nested: Is a list of dictionaries with the full information for each one of the authors of the article.

- -
-
-
-
- -
- -
-
- -
-
-
df.columns
-
- -
-
-
- -
-
- -
-
- - - -
-
Index(['comment', 'reference', 'abstract', 'creation_date', 'imprint',
-       'primary_report_number', 'keywords', 'publication_info', 'coyright',
-       'subject', 'cataloguer_info', 'physical_description',
-       'number_of_citations', 'other_report_number', 'title',
-       'persistent_identifiers_keys', 'corporate_name', 'files',
-       'system_control_number', 'filenames', 'source_of_acquisition',
-       'number_of_reviews', 'version_id', 'FIXME_OAI', 'authors', 'doi',
-       'number_of_authors', 'license', 'accelerator_experiment',
-       'number_of_comments', 'url', 'recid', 'collection', 'thesaurus_terms',
-       'filetypes', 'prepublication'],
-      dtype='object')
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
df.number_of_authors
-
- -
-
-
- -
-
- -
-
- - - -
-
0    2279
-Name: number_of_authors, dtype: int64
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
df.authors
-
- -
-
-
- -
-
- -
-
- - - -
-
0    [{'INSPIRE_number': 'INSPIRE-00312131', 'affiliation': 'Yerevan Phys. Inst.', 'first_name': 'Albert M', 'last_name': 'Sirunyan', 'full_name': 'Sirunyan, Albert M'}, {'INSPIRE_number': 'INSPIRE-001...
-Name: authors, dtype: object
-
- -
-
-
-
- -
-
- -
- -
-
-

Activity: Check that the lenght of the auhors list coincides with the number_of_authors -

- -
-
-
-
- -
- -
-
- -
-
-
df.authors.apply(len)
-
- -
-
-
- -
-
- -
-
- - - -
-
0    2279
-Name: authors, dtype: int64
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
df.authors[0][0]
-
- -
-
-
- -
-
- -
-
- - - -
-
{'INSPIRE_number': 'INSPIRE-00312131',
- 'affiliation': 'Yerevan Phys. Inst.',
- 'first_name': 'Albert M',
- 'last_name': 'Sirunyan',
- 'full_name': 'Sirunyan, Albert M'}
-
- -
-
-
-
- -
-
- -
- -
-
-

We can use all the previous methods to extract the authors from 'Antioquia U.':

-

Note: For a dictionary, d is safer to use d.get('key') instead of just d['key'] to obtain some key, because not error is generated if the requested key does not exists at all

- -
-
-
-
- -
- -
-
- -
-
-
df.authors.apply(lambda l: [d for d in l if d.get('affiliation')=='Antioquia U.']).loc[0]
-
- -
-
-
- -
-
- -
-
- - - -
-
[{'INSPIRE_number': 'INSPIRE-00343518',
-  'affiliation': 'Antioquia U.',
-  'first_name': 'Jhovanny',
-  'last_name': 'Mejia Guisao',
-  'full_name': 'Mejia Guisao, Jhovanny'},
- {'INSPIRE_number': 'INSPIRE-00355050',
-  'affiliation': 'Antioquia U.',
-  'first_name': 'José David',
-  'last_name': 'Ruiz Alvarez',
-  'full_name': 'Ruiz Alvarez, José David'}]
-
- -
-
-
-
- -
-
- -
- -
-
-

We also need use comprenhension list like in

- -
-
-
-
- -
- -
-
- -
-
-
l=[1,2,3]
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
[x if x>1 else 3 for x in l ]
-
- -
-
-
- -
-
- -
-
- - - -
-
[3, 2, 3]
-
- -
-
-
-
- -
-
- -
- -
-
-

Then the on-fly apply function to extract the authors with affiliation 'Antioquia U.' is

- -
-
-
-
- -
- -
-
- -
-
-
df.authors.apply(lambda l:  #implicit function
-                           [ d.get('full_name') #safer way to obtain a `key` value
-                             for d in l   #comprehension list 
-                              if isinstance(d,dict) and d.get('affiliation')=='Antioquia U.' #condition
-                           ] 
-                             if isinstance(l,list) else None #  Be sure that cell have the proper format
-                 )
-
- -
-
-
- -
-
- -
-
- - - -
-
0    [Mejia Guisao, Jhovanny, Ruiz Alvarez, José David]
-Name: authors, dtype: object
-
- -
-
-
-
- -
-
- -
- -
-
-

A simpler version is possible, but is more prompted to error when used through multiple column entries:

- -
-
-
-
- -
- -
-
- -
-
-
df.authors.apply(lambda l: [ d['full_name'] for d in l   
-                              if d['affiliation']=='Antioquia U.'
-                           ] )
-
- -
-
-
- -
-
- -
-
- - - -
-
0    [Mejia Guisao, Jhovanny, Ruiz Alvarez, José David]
-Name: authors, dtype: object
-
- -
-
-
-
- -
-
- - - -
- -
-
-

Activity: Repeat the same activity but using directly the JSON file

- -
-
-
-
- -
- -
-
-

NOTE: The same but with the new API

- -
-
-
-
- -
- -
-
- -
-
-
#See: https://github.com/inspirehep/rest-api-doc/issues/4#issuecomment-645218074
-import requests                                                                                                                                                      
-response = requests.get('https://inspirehep.net/api/doi/10.1103/PhysRevLett.122.132001')                                                                              
-authors = response.json()['metadata']['authors']                                                                                                                     
-names = [author.get('full_name')
-              for author in authors 
-               if any(aff.get('value') == 'Antioquia U.' for aff in author.get('affiliations'))]
-names
-
- -
-
-
- -
-
- -
-
- - - -
-
['Mejia Guisao, Jhovanny', 'Ruiz Alvarez, José David']
-
- -
-
-
-
- -
-
- - - -
- -
-
-

Final remarks

With basic scripting and Pandas we already have a solid environment to analyse data. We introduce the other libraries motivated with the extending the capabilities of Pandas

- -
-
-
-
- - - - -
- \ No newline at end of file diff --git a/_build/features/algorithms-convergence.html b/_build/features/algorithms-convergence.html deleted file mode 100644 index d4f6762..0000000 --- a/_build/features/algorithms-convergence.html +++ /dev/null @@ -1,603 +0,0 @@ ---- -interact_link: content/features/algorithms-convergence.ipynb -kernel_name: python3 -kernel_path: content/features -has_widgets: false -title: |- - Algorithms and convergence -pagenum: 7 -prev_page: - url: /features/computer-arithmetics.html -next_page: - url: /features/numba.html -suffix: .ipynb -search: algorithms n computing convergence iterations p exponential j algorithm linear unstable example pn b initial sum colab stable where equation given conditions required frac large vec r e solution computer types however interesting performed scaling consider function small perturbation mi total energy th particle research google com must problem refer among usually recursive cdots any constants setting implying show float arithmetics lead error also random numbers type scales left right change category useful ones important well due ei g neq mj want calculate tot mathcal o result codes font href github restrepo computationalmethods blob master material ipynb target parentimg src - -comment: "***PROGRAMMATICALLY GENERATED, DO NOT EDIT. SEE ORIGINAL FILES IN /content***" ---- - -
-
Algorithms and convergence
-
-
- -
-
-

Open In Colab

-

Algorithms and Convergence

In simple terms, an algorithm can be defined as a finite sequence of unambiguous steps that must be followed in order to solve or approximate the solution to some problem. The stated procedure should be translatable into computer code through a programming language.

-
- -
-

There several ways to classify an algorithm, however those that refer to their numerical convergence and accuracy are more interesting. Among them we have:

- -
-
-
-
- -
- -
-
- -
-
-
%pylab inline
-
- -
-
-
- -
-
- -
-
- -
-
Populating the interactive namespace from numpy and matplotlib
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
import numpy as np
-
- -
-
-
- -
-
- -
- -
-
-
- -
-
-
-
- -
- -
-
-

Types of Algorithms

-
-
-
-
- -
- -
-
-

Linear algorithms

-
-
-
-
- -
- -
-
-

They are algorithms where errors scale as the number of performed iterations. This definition usually coincides with the scaling of the time computing.

- -
-
-
-
- -
- -
-
-

Example 1:

-

Consider the recursive equation:

-$$ p_n = 2 p_{n-1} - p_{n-2},\ \ \ \ n = 2,3,\cdots $$

the solution to this equation for $p_n$ is given by

-$$ p_n = A + Bn $$

for any constants $A$ and $B$.

-

Setting the initial conditions as $p_0=1$ and $p_1 = 1/3$ (implying $A=1$ and $B=-2/3$), show that a float32 arithmetics would lead a linear error scaling as the number of iterations $n$.

- -
-
-
-
- -
- -
-
- -
-
-
#Number of iterations
-Niter = 10000
-
-#Double precision constants (Exact solution)
-A_d = 1.0
-B_d = -2/3.
-#Signle precision constants
-A_s = 1.0000000
-B_s = -0.666667
-
-#Solution to n-th term
-pn = lambda A, B, n: A + B*n
-
-#Arrays for storing the iterations
-p_d = []
-p_s = []
-narray = range(Niter)
-for n in narray:
-    p_d.append( pn( A_d, B_d, n ) )
-    p_s.append( pn( A_s, B_s, n ) )
-
-#Converting to numpy arrays
-p_d = np.array(p_d)
-p_s = np.array(p_s)
-
-#Relative error
-error = p_d - p_s
-plt.plot( narray, error, "-", color="blue" )
-plt.xlabel("Number of iterations $n$", fontsize=14)
-plt.ylabel("Error $p_n-\hat{p}_n$", fontsize=14)
-plt.grid(True)
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Example 2:

-

A linear algorithm may also refer to the computing time required for performing $n$ iterations. This example evaluates the time required for evaluating the sum of $N$ random numbers as a function of how many number are going to be added. A comparison with the built-in function of python is also performed.

- -
-
-
-
- -
- -
-
- -
-
-
#New library!!! 
-#Time: this library allows to access directly to the computer time. 
-#      Useful when time calculations are required.
-import time as tm
-
-#Maximum number of iterations
-narray = 10**np.arange(1,7,0.1)
-
-#Time arrays
-t_u = []  #User
-t_p = []  #Python
-
-#Iterations
-for n in narray:
-    #Generating random numbers
-    N = np.random.random(n)
-    #-------------------------------------------------------------------
-    # MANUAL SUMMATION
-    #-------------------------------------------------------------------
-    #Starting time counter for user
-    start = tm.clock()
-    #Adding the numbers manually
-    result = 0
-    for i in xrange(int(n)):
-        result += N[i]
-    #Finishing time counter for user
-    end = tm.clock()
-    #Storing result
-    t_u.append( end-start )
-    
-    #-------------------------------------------------------------------
-    # PYTHON SUMMATION
-    #-------------------------------------------------------------------
-    #Starting time counter for user
-    start = tm.clock()
-    #Adding the numbers using python
-    result = np.sum( N )
-    #Finishing time counter for user
-    end = tm.clock()
-    #Storing result
-    t_p.append( end-start )
-    
-#Ploting
-plt.semilogx( narray, t_u, "-", color="red", linewidth=2, label="Manual" )
-plt.semilogx( narray, t_p, "-", color="blue", linewidth=2, label="Python" )
-plt.xlabel("Number of taken numbers $N$", fontsize=14)
-plt.ylabel("Computing time [seconds]", fontsize=14)
-plt.grid(True)
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Exponential algorithms

-
-
-
-
- -
- -
-
-

This type of algorithms scales as an exponential factor of the number of iterations. These algorithms are usually unstable, where a small perturbation leads to a exponential growth after a few iterations.

- -
-
-
-
- -
- -
-
-

Example 3:

-

Consider the recursive equation:

-$$ p_n = \frac{10}{3}p_{n-1} - p_{n-2},\ \ \ \ n = 2,3,\cdots $$

the solution to this equation for $p_n$ is given by

-$$ p_n = A\left( \frac{1}{3} \right)^n + B\ 3^n $$

for any constants $A$ and $B$.

-

Setting the initial conditions as $p_0=1$ and $p_1 = 1/3$ (implying $A=1$ and $B=0$), show that a float32 arithmetics would lead an error scaling as the exponential of the number of iterations $n$.

- -
-
-
-
- -
- -
-
- -
-
-
#Number of iterations
-Niter = 100
-
-#Double precision constants (Exact solution)
-A_d = 1.0
-B_d = 0.
-
-#Solution to n-th term
-pn = lambda A, B, n: A*(3.0)**-n + B*(3.0)**n
-
-#Arrays for storing the iterations
-p_s = [1.000000,0.333333]
-p_d = [1.,1/3.]
-
-narray = range(Niter)
-for n in narray[2:]:
-    p_s.append( 10/3.*p_s[n-1]-p_s[n-2] )
-    p_d.append( pn( A_d, B_d, n ) )
-
-#Converting to numpy arrays
-p_d = np.array(p_d)
-p_s = np.array(p_s)
-
-#Relative error
-error = p_d - p_s
-plt.semilogy( narray, error, "-", color="blue" )
-plt.xlabel("Number of iterations $n$", fontsize=14)
-plt.ylabel("Error $p_n-\hat{p}_n$", fontsize=14)
-plt.grid(True)
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Stable algorithms

-
-
-
-
- -
- -
-
-

These algorithms exhibit a small change when an initial perturbation to the initial conditions is introduced. Linear algorithms can be catalogued within this category.

- -
-
-
-
- -
- -
-
-

Unstable algorithms

-
-
-
-
- -
- -
-
-

Unlike stable algorithms, unstable algorithms produce a large change when iterating with respect to a small perturbation in the initial conditions. Exponential algorithms fit in this category.

-

At first glance, unstable algorithms may seem undesirable, however there are some useful applications for them. Among the more interesting ones is the generation of random numbers in a computer. Pseudorandom number generator

- -
-
-
-
- -
- -
-
-
- -
-
-
-
- -
- -
-
-

Computing Time

-
-
-
-
- -
- -
-
-

One of the most important skills a programmer must develop is to evaluate the computing time of certain process as well as the consumed memory. When computational resources are limited (as always happens!), estimating beforehand the computing time of an algorithm is certainly important.

- -
-
-
-
- -
- -
-
-

Example 4:

-

An interesting example that illustrates very well the issue of computing time is the N-body problem.

-

Consider a set of $N$ masses $\{m_i\}$. The total gravitational potential energy of the $i$-th particle due to the other ones is given by

-$$E_i = -G\sum_{j=1, j\neq i}^N \frac{m_i m_j}{|\vec{r}_i-\vec{r}_j|}$$

Now, if we want to calculate the total energy of the system, it is necessary to add each contribution, i.e.

-$$E_{tot} = \sum_{i=1}^N E_i = \sum_{i=1}^N \left( -G\sum_{j=1, j\neq i}^N \frac{m_i m_j}{|\vec{r}_i-\vec{r}_j|} \right) $$

This implies if we want to calculate $E_{tot}$ in a computer, it is required $N(N-1)\approx N^2$ iterations, so the computing time scales as $\mathcal{O}(N^2)$. An estimation of the total time is then reached by first measuring the required time for 1 iteration, i.e., the energy of the $i$-th particle due to the $j$-th particle, and then multiplying the result by $N^2$.

-

The large computing time of this type of algorithms (when $N$ becomes large enough) has propelled a large enterprise of more efficient algorithms, including tree-codes where the computing time is reduced to $\mathcal{O}(N \log N)$

- -
-
-
-
- -
- -
-
- -
-
-
N = np.arange(1,1e3,0.1)
-plt.loglog( N, N**2, linewidth=2, label="$N^2$" )
-plt.loglog( N, N*np.log(N), linewidth=2, label="$N\ \log N$" )
-plt.legend( loc="upper left" )
-plt.grid(True)
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-
- -
-
-
-
- -
- -
-
-

Convergence

-
-
-
-
- -
- -
-
-

The last concept related to algorithms is convergence. This refers to how fast an algorithm can reach a desired result with some given precision. Some rigorous techniques can be used to quantify the convergence degree, however it is commonly a more useful approach to compare the convergence of an algorithm with other already known.

- -
-
-
-
- -
- -
-
-

-ACTIVITY

-

In a IPython notebook and using the codes of the first task, make a figure where is compared the values obtained for the two methods for calculating $\pi$ as a function of the number of performed iterations. Which method reaches a faster convergence? -</font>

- -
-
-
-
- -
- -
-
-
- -
-
-
-
- - - - -
- \ No newline at end of file diff --git a/_build/features/computer-arithmetics.html b/_build/features/computer-arithmetics.html deleted file mode 100644 index 009e492..0000000 --- a/_build/features/computer-arithmetics.html +++ /dev/null @@ -1,2030 +0,0 @@ ---- -interact_link: content/features/computer-arithmetics.ipynb -kernel_name: python3 -kernel_path: content/features -has_widgets: false -title: |- - Mathematical Preliminaries -pagenum: 6 -prev_page: - url: /features/ipython-notebooks.html -next_page: - url: /features/algorithms-convergence.html -suffix: .ipynb -search: numbers binary bits b precision s frac representation quotient arithmetic float python sum svg e operations single double org real com represent finite next int wikipedia x computer used represented any not addition divide remainder previous activity function string d floatexample times integer set multiplication here digits step new format need base digit formula np colab off example within errors machine www last obtain r integers implement following full upload wikimedia commons thumb px png system where rules sign given result n xe print u round v computation numerical called representable taken error must into values zeroes standard check font - -comment: "***PROGRAMMATICALLY GENERATED, DO NOT EDIT. SEE ORIGINAL FILES IN /content***" ---- - -
-
Mathematical Preliminaries
-
-
- -
-
-

Open In Colab

-

Computer Arithmetics and Round-off Methods

Actividades: https://classroom.github.com/a/2v-HnNqn

-

In a symbolic computation programs, implemented in SymPy or Mathematica for example, operatios like $1/3+4/3=5/3$, $2\times 3/4 = 3/2$, $(\sqrt{2})^2 = 2$ are unambiguously defined, However, when one numerical programming languages are used to represent numbers in a computer, this is no longer true. The main reason of this is the so-called finite arithmetic, what is the way in which a numerical computer programs performs basic operations. Some features of finite arithmetic are stated below:

- -
-
-
-
- -
- -
-
-
    -
  • Only integer and rational numbers can be exactly represented.
  • -
  • The elements of the set in which arithmetic is performed is necessarily finite.
  • -
  • Any arithmetic operation between two or more numbers of this set should be another element of the set.
  • -
  • Non-representable numbers like irrational numbers are approximated to the closest rational number within the defined set.
  • -
  • Extremely large numbers produce overflows and extremely small numbers produce underflows, which are taken as null.
  • -
  • Operations over non-representable numbers are not exact.
  • -
-

In spite of this, defining adequately the set of elements in which our computer will operate, round-off methods can be systematically neglected, yielding correct results within reasonable error margins. In some pathological cases, when massive iterations are required, these errors must be taken into account more seriously.

-
- -
- -
-
-
-
- -
- -
-
-

More About Float Values

See also here

-

In Python a float only represents 15 or 16 significant digits for any number; the remaining precision is lost. This limited precision is enough for the vast majority of applications.

-

In the next evaluation extra digits are discarded before any arithmetic is carried out.

- -
-
-
-
- -
- -
-
- -
-
-
0.6666666666666666 - 0.6666666666666666123456789
-
- -
-
-
- -
-
- -
-
- - - -
-
0.0
-
- -
-
-
-
- -
-
- -
- -
-
-

After combining float values with arithmetic, the last few digits may be incorrect. Small rounding errors are often confusing when first encountered. For example, the expression 2**0.5 computes the square root of 2, but squaring this value does not exactly recover 2.

- -
-
-
-
- -
- -
-
- -
-
-
2**0.5
-
- -
-
-
- -
-
- -
-
- - - -
-
1.4142135623730951
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
(2**0.5)**2
-
- -
-
-
- -
-
- -
-
- - - -
-
2.0000000000000004
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
(2**0.5)**2 - 2
-
- -
-
-
- -
-
- -
-
- - - -
-
4.440892098500626e-16
-
- -
-
-
-
- -
-
- -
- -
-
-

Binary machine numbers

-
-
-
-
- -
- -
-
-

We will obtain the general algorithm to obtain the binary r

- -
-
-
-
- -
- -
-
-

Integers

-
-
-
-
- -
- -
-
-

From here: If you recall your mathematics, then it will be easy for you to find out how we turn an integer number to its binary representation. Let's take for example the number 47. (see '//' operator here)

-
    -
  1. We divide 47 by 2. The quotient is int(47//2) → 23 and the remainder is 47%2 → 1
  2. -
  3. We divide the quotient of the previous step by 2. The new quotient is int(23//2) → 11 and the remainder is 23%2 → 1.
  4. -
  5. We divide the quotient of the previous step by 2. The new quotient is int(11/2) → 5 and the remainder is 11%2 → 1.
  6. -
  7. We divide the quotient of the previous step by 2. The new quotient is int(5//2) → 2 and the remainder is 5%2 → 1.
  8. -
  9. We divide the quotient of the previous step by 2. The new quotient is int(2//2) → 1 and the remainder is 2%2 → 0.
  10. -
  11. We divide the quotient of the previous step by 2. The new quotient is int(1//2) → 0 and the remainder is 1%2 → 1
  12. -
  13. We stop here, when the last quotient is 1//2→0.
  14. -
-

Then, the binary representation is the series of 1s and 0s of the remainders, taken in reverse order to the one produced, from latest to earliest: 101111. -

- -
-
-
-
- -
- -
-
-

Activity: Implement a function that get the binary representation of an integer.

- -
-
-
-
- -
- -
-
-

Activity: Return as a string with 8 charactes completed with leading zeroes. Use the string method: .rjust(8,"0")

- -
-
-
-
- -
- -
-
-

Activity Write your function in the following format

- -
-
-
-
- -
- -
-
- -
-
-
#!/usr/bin/env python3
-def mybin(x):
-    print('__name__ = {}'.format(__name__))
-    #Write your code here and change the next line as required
-    return bin(x)[2:].rjust(8, "0")
-if __name__=='__main__':
-    n=input('Escriba un entero:\n')
-    b=mybin(int(n))
-    print('Su representación binaria es: {}'.format(b))
-
- -
-
-
- -
-
- -
-
- -
-
Overwriting mybin.py
-
-
-
-
-
-
- -
-
- -
- -
-
-

The advantage of this standard format is that can be used directly as a python module, because in that case the variable __name__ evaluates to the name -of the function. To check this, we first use a cell of the notebook just as a editor with the Jupyter magic function %%writefile

- -
-
-
-
- -
- -
-
- -
-
-
%%writefile mybin.py
-#!/usr/bin/env python3
-def mybin(x):
-    print('__name__ = {}'.format(__name__))
-    return bin(x)[2:].rjust(8, "0")
-if __name__=='__main__':
-    n=input('Escriba un entero;\n')
-    b=mybin(int(n))
-    print('Su representación binaria es: {}'.format(b))
-
- -
-
-
- -
-
- -
-
- -
-
Overwriting mybin.py
-
-
-
-
-
-
- -
-
- -
- -
-
-

We now can use the full contents of the file as an usual python module, it it is -in the working directory

- -
-
-
-
- -
- -
-
- -
-
-
import mybin as my
-my.mybin(45)
-
- -
-
-
- -
-
- -
-
- -
-
__name__ = mybin
-
-
-
-
-
-
- - - -
-
'00101101'
-
- -
-
-
-
- -
-
- -
- -
-
-

while here, or in a terminal:

- -
-
-
-
- -
- -
-
- -
-
-
__name__
-
- -
-
-
- -
-
- -
-
- - - -
-
'__main__'
-
- -
-
-
-
- -
-
- -
- -
-
-

Check with bin

- -
-
-
-
- -
- -
-
-

The binary representation of a float in 32 bits done by the following steps

- -
-
-
-
- -
- -
-
- -
-
-
bin(47)
-
- -
-
-
- -
-
- -
-
- - - -
-
'0b101111'
-
- -
-
-
-
- -
-
- -
- -
-
-

The format is not the standard one. We need drop the first '0b'

- -
-
-
-
- -
- -
-
- -
-
-
bin(47)[2:]
-
- -
-
-
- -
-
- -
-
- - - -
-
'101111'
-
- -
-
-
-
- -
-
- -
- -
-
-

We must enforce the 8 bits representation by padding any additional leading zeroes

- -
-
-
-
- -
- -
-
- -
-
-
bin(47)[2:].rjust(8, '0')
-
- -
-
-
- -
-
- -
-
- - - -
-
'00101111'
-
- -
-
-
-
- -
-
- -
- -
-
-

To convert a binary into the integer we can use the int function with base=0 upont the proper Python formatted string, starting with: `0b`

- -
-
-
-
- -
- -
-
- -
-
-
int('0b101111',base=0)
-
- -
-
-
- -
-
- -
-
- - - -
-
47
-
- -
-
-
-
- -
-
- -
- -
-
-

or with any number of padding zeroes in between

- -
-
-
-
- -
- -
-
- -
-
-
int('0b0000000101111',base=0)
-
- -
-
-
- -
-
- -
-
- - - -
-
47
-
- -
-
-
-
- -
-
- -
- -
-
-

Floats

Floats in 32 bits are representated trough 4 8-bit integers.

-

The processes of obtain the binary representation for a float can be complicated because the design used to really store the number in one specific programming language like Python. In fact, from https://stackoverflow.com/a/16444778/2268280:

- -
-
-
-
- -
- -
-
-
    -
  • To obtain the four integers associated to a real number we need first to ask for the packed structure : '!', in 32 bits: 'f', with the full string '!f' as
  • -
- -
-
-
-
- -
- -
-
- -
-
-
import struct
-packed=struct.pack('!f',0.15625)
-packed
-
- -
-
-
- -
-
- -
-
- - - -
-
b'> \x00\x00'
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
type(packed)
-
- -
-
-
- -
-
- -
-
- - - -
-
bytes
-
- -
-
-
-
- -
-
- -
- -
-
-

This is a packed Python list with the four integers inside

- -
-
-
-
- -
- -
-
- -
-
-
[n for n in packed]
-
- -
-
-
- -
-
- -
-
- - - -
-
[62, 32, 0, 0]
-
- -
-
-
-
- -
-
- -
- -
-
-

Using the previous function to convert into a list of 8-bit strings

- -
-
-
-
- -
- -
-
- -
-
-
lb=[ mybin(n) for n in packed]
-lb
-
- -
-
-
- -
-
- -
-
- -
-
__name__ = __main__
-__name__ = __main__
-__name__ = __main__
-__name__ = __main__
-
-
-
-
-
-
- - - -
-
['00111110', '00100000', '00000000', '00000000']
-
- -
-
-
-
- -
-
- -
- -
-
-

The float representation is just the string formed with the four binaries

- -
-
-
-
- -
- -
-
- -
-
-
''.join(lb)
-
- -
-
-
- -
-
- -
-
- - - -
-
'00111110001000000000000000000000'
-
- -
-
-
-
- -
-
- -
- -
-
-

32-bits

- -
-
-
-
- -
- -
-
-

Full implementation

-
-
-
-
- -
- -
-
- -
-
-
import struct
-
-def binary(num):
-#num=3
-#if True:
-    # Struct can provide us with the float packed into bytes. The '!' ensures that
-    # it's in network byte order (big-endian) and the 'f' says that it should be
-    # packed as a float: 32 bites. Alternatively, for double-precision, you could use 'd'.
-    packed = struct.pack('!f', num)
-    print( 'Packed: %s' % repr(packed))
-
-    # For each character in the returned string, we'll turn it into its corresponding
-    # integer code point
-    # 
-    integers = [c for c in packed]
-    print( 'Integers: %s' % integers)
-
-    # For each integer, we'll convert it to its binary representation.
-    binaries = [bin(i) for i in integers]
-    print( 'Binaries: %s' % binaries)
-
-    # Now strip off the '0b' from each of these
-    stripped_binaries = [s.replace('0b', '') for s in binaries]
-    print( 'Stripped: %s' % stripped_binaries)
-
-    # Pad each byte's binary representation's with 0's to make sure it has all 8 bits:
-    #
-    # ['00111110', '10100011', '11010111', '00001010']
-    padded = [s.rjust(8, '0') for s in stripped_binaries]
-    print( 'Padded: %s' % padded)
-
-    # At this point, we have each of the bytes for the network byte ordered float
-    # in an array as binary strings. Now we just concatenate them to get the total
-    # representation of the float:
-    return ''.join(padded)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
BIN=binary(0.15625)
-BIN
-
- -
-
-
- -
-
- -
-
- -
-
Packed: b'> \x00\x00'
-Integers: [62, 32, 0, 0]
-Binaries: ['0b111110', '0b100000', '0b0', '0b0']
-Stripped: ['111110', '100000', '0', '0']
-Padded: ['00111110', '00100000', '00000000', '00000000']
-
-
-
-
-
-
- - - -
-
'00111110001000000000000000000000'
-
- -
-
-
-
- -
-
- -
- -
-
-

32-bits

- -
-
-
-
- -
- -
-
- -
-
-
''.join( list(BIN)[::-1] ) #inverted list joined into a string
-
- -
-
-
- -
-
- -
-
- - - -
-
'00000000000000000000010001111100'
-
- -
-
-
-
- -
-
- -
- -
-
-

Binary machine numbers

-
-
-
-
- -
- -
-
-

As everyone knows, the base of the modern computation is the binary numbers. The binary base or base-2 numeral system is the simplest one among the existing numeral bases. As every electronic devices are based on logic circuits (circuits operating with logic gates), the implementation of a binary base is straightforward, besides, any other numeral system can be reduced to a binary representation.

-

LogicGates

-

According to the standard IEEE 754-2008, representation of real numbers can be done in several ways, single-precision and double precision are the most used ones.

- -
-
-
-
- -
- -
-
-

Single-precision numbers

-
-
-
-
- -
- -
-
-

Single-precision numbers are used when one does not need very accurate results and/or need to save memory. These numbers are represented by a 32-bits (Binary digIT) lenght binary number, where the real number is stored following the next rules:

-

32-bits

-
    -
  1. The fist digit (called s) indicates the sign of the number (s=0 means a positive number, s=1 a negative one).
  2. -
  3. The next 8 bits represent the exponent of the number.
  4. -
  5. The last 23 bits represent the fractional part of the number.
  6. -
-

The formula for recovering the real number is then given by:

-$$r = \frac{(-1)^s}{2^{127-e}} \left( 1 + \sum_{i=0}^{22}\frac{b_{i}}{2^{23-i}} \right)$$

where $s$ is the sign, $b_{23-i}$ the fraction bits and $e$ is given by:

-$$e = \sum_{i=0}^7 b_{23+i}2^i$$

Next, it is shown a little routine for calculating the value of the represented 32-bits number

- -
-
-
-
- -
- -
-
-

ACTIVITY

With the binary representation please try to implement the formula to recover the number.

-

Hint: Use as input the binary representation as a string and invert its order

- -
-
-
-
- -
- -
-
-

SOLUTION:

- -
-
-
-
- -
- -
-
-

The goal of this course is try to implement all the algorithms in terms of array operations, instead of use the loops of Pyhton like the for loop.

-

In this way, we need to interpret the formula in terms of arrays operations. If we manage to achieve that, then NumPy will be take care of the internal loops, which are much faster than the Python loops. As a bonus, the code is more compact and readable.

-

For example:

-\begin{align} -\sum_{i=0}^{22}\frac{b_{i}}{2^{23-i}}=&\frac{b[0]}{2^{23}}+\frac{b[1]}{2^{22}} - +\cdots +\frac{b[21]}{2^2}+\frac{b[22]}{2^1}\nonumber\\ -=&\frac{b}{2^{[23,22,...,1]}}.\operatorname{sum()}\nonumber\\ -=&\frac{b}{2^{[1,2,...,23][::-1]}}.\operatorname{sum()} -\end{align}

To implement the full formula: -$$r = \frac{(-1)^s}{2^{127-e}} \left( 1 + \sum_{i=0}^{22}\frac{b_{i}}{2^{23-i}} \right)$$ -with -$$e = \sum_{i=0}^7 b_{23+i}2^i$$

-$$e_{\text{max}} = \sum_{i=0}^7 2^i$$

Note that -we have

- -
-
-
-
- -
- -
-
- -
-
-
import numpy as np
-def number32(BIN):
-#if True:
-    #BIN='00111110001000000000000000000000'
-    #Inverting binary string
-    b_inverted=np.array(list(BIN)[::-1]).astype(int)
-    
-    s=b_inverted[31]
-    #Exponent part
-    be=b_inverted[23:31]
-    i=np.arange(be.size)
-    e=(be*(2**i)).sum()
-    
-    bf=b_inverted[0:23]
-    i_inverted=np.arange(1,bf.size+1)[::-1]
-
-
-    numero=( (-1)**s/2**(127-e)  )*( 1 + (bf/2**i_inverted).sum() ) 
-    return numero
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
print(number32('00111110001000000000000000000000'))
-
- -
-
-
- -
-
- -
-
- -
-
0.15625
-
-
-
-
-
-
- -
-
- -
- -
-
-

Check aginst the implementation with for's

- -
-
-
-
- -
- -
-
- -
-
-
# %load numtobin.py
-def num32( binary ):
-    #Inverting binary string
-    binary = binary[::-1]
-    s=binary[31]
-    #Decimal part
-    dec = 1
-    for i in range(1,24):
-        dec += int(binary[23-i])*2**-i
-    #Exponent part
-    exp = 0
-    for i in range(0,8):
-        exp += int(binary[23+i])*2**i
-    #Total number
-    number =( (-1)**int(s)/2**(127-exp) )*dec
-    return number
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
print(num32('00111110001000000000000000000000'))
-
- -
-
-
- -
-
- -
-
- -
-
0.15625
-
-
-
-
-
-
- -
-
- -
- -
-
-

%load sln.py

- -
-
-
-
- -
- -
-
-

Single-precision system can represent real numbers within the interval $\pm 10^{-38} \cdots 10^{38}$, with $7-8$ decimal digits.

- -
-
-
-
- -
- -
-
- -
-
-
#Decimal digits 
-print("\n")
-print( "Decimal digits contributions for single precision number")
-print( 2**-23., 2**-15., 2**-5. , "\n")
-
-#Largest and smallest exponent  
-emax = 0 
-for i in range(0,8):
-    emax += 2**i
-print( "Largest and smallest exponent for single precision number" )
-print( 2**(emax-127.), 2**(-127.),"\n" )
-
- -
-
-
- -
-
- -
-
- -
-
-
-Decimal digits contributions for single precision number
-1.1920928955078125e-07 3.0517578125e-05 0.03125 
-
-Largest and smallest exponent for single precision number
-3.402823669209385e+38 5.877471754111438e-39 
-
-
-
-
-
-
-
- -
-
- -
- -
-
-

Double-precision numbers

-
-
-
-
- -
- -
-
-

Double-precision numbers are used when high accuracy is required. These numbers are represented by a 64-bits (Binary digIT) lenght binary number, where the real number is stored following the next rules:

-

64-bits

-
    -
  1. The fist digit (called s) indicates the sign of the number (s=0 means a positive number, s=1 a negative one).
  2. -
  3. The next 11 bits represent the exponent of the number.
  4. -
  5. The last bits represent the fractional part of the number.
  6. -
-

The formula for recovering the real number is then given by:

-$$r = (-1)^s\times \left( 1 + \sum_{i=1}^{52}b_{52-i}2^{-i} \right)\times 2^{e-1023}$$

where $s$ is the sign, $b_{23-i}$ the fraction bits and $e$ is given by:

-$$e = \sum_{i=0}^{10} b_{52+i}2^i$$

Double-precision system can represent real numbers within the interval $\pm 10^{-308} \cdots 10^{308}$, with $16-17$ decimal digits.

- -
-
-
-
- -
- -
-
- -
-
-
1e307 * 10
-
- -
-
-
- -
-
- -
-
- - - -
-
1e+308
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
1e307 * 20
-
- -
-
-
- -
-
- -
-
- - - -
-
inf
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
1e-323
-
- -
-
-
- -
-
- -
-
- - - -
-
1e-323
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
1e-324
-
- -
-
-
- -
-
- -
-
- - - -
-
0.0
-
- -
-
-
-
- -
-
- -
- -
-
-

ACTIVITY

1. Write a python script that calculates the double precision number represented by a 64-bits binary.

-

2. What is the number represented by:

-

0 10000000011 1011100100001111111111111111111111111111111111111111

-

- ANSWER: 27.56640625

- -
-
-
-
- -
- -
-
-

Finite Arithmetic

-
-
-
-
- -
- -
-
-

The most basic arithmetic operations are addition and multiplication. Further operations such as subtraction, division and power are secondary as they can be reached by iteratively use the latter ones.

- -
-
-
-
- -
- -
-
-

Addition

-
-
-
-
- -
- -
-
- -
-
-
-
- -
- -
-
- -
-
-
import numpy as np
-print("Error:", np.float32(5/7.+1/3.)-22/21.)
-
- -
-
-
- -
-
- -
-
- -
-
Error: 5.676632830464712e-08
-
-
-
-
-
-
- -
-
- -
- -
-
-

Therefore, at the numerical computation level we must be aware that an expected -zero result is really -$$0\approx 10^{-16}$$

- -
-
-
-
- -
- -
-
-

Multiplication

-
-
-
-
- -
- -
-
-

For multiplication it is applied the same round-off rules as the addition, however, be aware that multiplicative errors propagate more quickly than additive errors.

- -
-
-
-
- -
- -
-
- -
-
-
N = 20
-xe=1; x = 1
-for i in range(N):
-    xe *= float(2.0**(1.0/N))
-    x *= np.float16(2.0**(1.0/N))
-print('expected: {}; obtained: {}'.format(xe,x))
-
- -
-
-
- -
-
- -
-
- -
-
expected: 2.000000000000003; obtained: 1.9958053041750938
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
N = 20
-xe=1; x = 1
-for i in range(N):
-    xe *= 2.0**(1.0/N)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
np.float16(3.1415926535897932384626433832795028841971)
-
- -
-
-
- -
-
- -
-
- - - -
-
3.14
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
np.float32(3.1415926535897932384626433832795028841971)
-
- -
-
-
- -
-
- -
-
- - - -
-
3.1415927
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
float(3.1415926535897932384626433832795028841971)
-
- -
-
-
- -
-
- -
-
- - - -
-
3.141592653589793
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
np.float64(3.1415926535897932384626433832795028841971)
-
- -
-
-
- -
-
- -
-
- - - -
-
3.141592653589793
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
np.float128(3.1415926535897932384626433832795028841971)
-
- -
-
-
- -
-
- -
-
- - - -
-
3.141592653589793116
-
- -
-
-
-
- -
-
- -
- -
-
-

The final result has an error at the third decimal digit, one more than the case of addition.

- -
-
-
-
- -
- -
-
-

ACTIVITY

-

Find the error associated to the finite representation in the next operations

-$$ -x-u, \frac{x-u}{w}, (x-u)*v, u+v -$$

considering the values

-$$ -x = \frac{5}{7}, y = \frac{1}{3}, u = 0.71425 -$$$$ -v = 0.98765\times 10^5, w = 0.111111\times 10^{-4} -$$ -
-
-
-
- - - - -
- \ No newline at end of file diff --git a/_build/features/differential-equations.html b/_build/features/differential-equations.html deleted file mode 100644 index e5f5487..0000000 --- a/_build/features/differential-equations.html +++ /dev/null @@ -1,3521 +0,0 @@ ---- -interact_link: content/features/differential-equations.ipynb -kernel_name: python3 -kernel_path: content/features -has_widgets: false -title: |- - Diferential equations -pagenum: 23 -prev_page: - url: /features/linear-algebra-extra.html -next_page: - url: /features/medium_modelling_part_one.html -suffix: .ipynb -search: y t frac boldsymbol begin end bmatrix f m align u p order d equations x c problem dt r operatorname differential value leq z method delta g b k methods example font second system v mathbf where equation solution initial dy h partial rho w using com problems mass alpha pendulum boundary runge kutta previous quad theta motion set mbox color colab model point speed force numerical lets ti left right form red th ordinary eulers assume beta de activity ac space material ipynb change approx times such baseball however yi uk cos phase around its hf github.amrom.workers.devputationalmethods - -comment: "***PROGRAMMATICALLY GENERATED, DO NOT EDIT. SEE ORIGINAL FILES IN /content***" ---- - -
-
Diferential equations
-
-
- -
-
-

Open In Colab

- -
-
-
-
- -
- -
-
-

Differential Equations

-
-
-
-
- -
- -
-
-

Open In Colab

-

Differential equations is without doubt one of the more useful branch of mathematics in science. They are used to model problems involving the change of some variable with respect to another. Differential equations cover a wide range of different applications, ranging from ordinary differential equations (ODE) until boundary-value problems involving many variables. For the sake of simplicity, throughout this section we shall cover only ODE systems as they are more elemental and equally useful. First, we shall cover first order methods, then second order methods and finally, system of differential equations.

-

See:

- - -
-
-
-
- - - -
- -
-
- -
-
-
%pylab inline
-
- -
-
-
- -
-
- -
-
- -
-
Populating the interactive namespace from numpy and matplotlib
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
import numpy as np
-# JSAnimation import available at https://github.com/jakevdp/JSAnimation
-#from JSAnimation import IPython_display
-from matplotlib import animation
-
- -
-
-
- -
-
- -
- -
-
-
- -
-
-
-
- -
- -
-
-

Physical motivation

Momentum

In absence a forces a body moves freely to a constant velocity (See figure)

-

The quantity which can be associated with the change of speed of a body is the instantaneous momentum of a particle of mass $m$ moving with instantaneous velocity $\boldsymbol{v}$, given by -\begin{align} - \boldsymbol{p}=&\gamma m \mathbf{v}\,, &\text{where: } \gamma=&\frac{1}{\sqrt{1-{|\boldsymbol{v}|^2}/{c^2}}}\,, -\end{align} -and $c\approx 3\times 10^8\ $m/s is the speed of light.

-

If $\gamma\approx1$, or equivalent, sif $|\boldsymbol{v}|\ll c$: -\begin{align} - \boldsymbol{p}\approx &m \boldsymbol{v} -\end{align}

-

Equation of motion

Any change of the momentum can be atribuited to some force, $\boldsymbol{F}$. In fact, the Newton's second law can be defined in a general way as

-

The change of the momentum of particle is equal to the net force acting upon the system times the duration of the interaction

-
-

For one instaneous duration $\Delta t$, this law can be written as -$$ -\Delta \boldsymbol{p} = \boldsymbol{F}\Delta t,\qquad \Delta t \to 0 -$$ -or as the equation of motion, which is the differential equation -\begin{align} -\boldsymbol{F}=&\lim_{t\to 0} \frac{\Delta \boldsymbol{p}}{\Delta t} \\ -\boldsymbol{F}=&\frac{\operatorname{d}\boldsymbol{p}}{\operatorname{d} t} \,. -\end{align} -This equation of motion is of general validity and can be applied numerically to solve any problem.

-

Constant mass

In the special case of constant mass -\begin{align} -\boldsymbol{F}=&m \boldsymbol{a} -\end{align}

- -
-
-
-
- -
- -
-
-

Example: Drag force

For a body falling in the air, in addition to the gravitiy force $\boldsymbol{W}$, there is a dragging force in the opposite direction given by [see here for details])img -$$ -F_D=\frac{1}{2}{\rho A C_d} v^2(t)=\frac{1}{2m^2}{\rho A C_d} p^2(t)\,, -$$ -where

-
    -
  • $A$: is the frontal area on a plane perpendicular to the direction of motion—e.g. for objects with a simple shape, such as a sphere
  • -
  • $\rho$ is the density of the air
  • -
  • $C_d$: Drag coefficient. $C_d=0.346$ for a baseball
  • -
  • $v(t)$: speed of the baseball
  • -
  • $p(t)$: momentum of baseball
  • -
-

The equation of motion is -\begin{align} -W-F_D=& \frac{d p}{dt}\\ -\frac{d p}{dt}=&m g - \frac{\rho A C_d}{2m^2} p^2(t). -\end{align}

-

We see then that, in general -$$ -\frac{d p}{dt}=f(t,p)\,. -$$

- -
-
-
-
- -
- -
-
-
- -
-
-
-
- -
- -
-
-

Mathematical background

Ordinary differential equations normally implies the solution of an initial-value problem, i.e., the solution has to satisfy the differential equation together with some initial condition. Real-life problems usually imply very complicated problems and even non-soluble ones, making any analytical approximation unfeasible. Fortunately, there are two ways to handle this. First, for almost every situation, it is generally posible to simplify the original problem and obtain a simpler one that can be easily solved. Then, using perturbation theory, we can perturbate this solution in order to approximate the real one. This approach is useful, however, it depends very much on the specific problem and a systematic study is rather complicated.

-

The second approximation, and the one used here, consists of a complete numerical reduction of the problem, solving it exactly within the accuracy allowed by implicit errors of the methods. For this part, we are going to assume well-defined problems, where solutions are expected to be well-behaved.

- -
-
-
-
- -
- -
-
-

Euler's method

First order differential equations

-
-
-
-
- -
- -
-
-

This method is the most basic of all methods, however, it is useful to understand basic concepts and definitions of differential equations problems.

-

Suppose we have a well-posed initial-value problem given by:

-$$ \frac{dy}{dt}=f(t,y),\ \ \ a\leq t\leq b, \ \ \ \ y(a) = \alpha $$

Now, let's define a mesh points as a set of values $\{t_i\}$ where we are going to approximate the solution $y(t)$. These points can be equal-spaced such that

-$$ t_i = a+ i \Delta t,\ \ \ \ \mbox{with}\ \ i=1,2,3,\cdots,N \ \ \mbox{and}\ \Delta t = \frac{b-a}{N}. $$

Here, $h$ is called the step size of the mesh points.

-

Now, using the first-order approximation of the derivative that we saw in Numerical Differentiation, we obtain

-$$ \frac{dy}{dt}\approx \frac{y(t+\Delta t)-y(t)}{\Delta t} $$

or

-$$ \left.\frac{dy}{dt}\right|_{t=t_i}\approx \frac{y(t_{i+1})-y(t_i)}{\Delta t} $$

The original problem can be rewritten as

-$$ y_{i+1} = y_i + f(t_i, y_i)\Delta t \pm \frac{\Delta t^2}{2}y^{''}(\xi_i) $$

where the notation $y(t_i)\equiv y_i$ has been introduced and the last term (error term) can be obtained taking a second-order approximation of the derivative. $\xi_i$ is the value that give the maximum in absolute value for $y''$

-

This equation can be solved recursively as we know the initial value $y_0 = y(a) = \alpha$.

- -
-
-
-
- -
- -
-
-

Second order differential equations

-
-
-
-
- -
- -
-
-

The formalism of the Euler's method can be applied for any system of the form:

-$$ \frac{dy}{dt}=f(t,y),\ \ \ a\leq t\leq b, \ \ \ \ y(a) = \alpha $$

However, it is possible to extend this to second-order systems, i.e., systems involving second derivatives. Let's suppose a general system of the form:

-$$ \frac{d^2y}{dt^2}+ g(t,y)\frac{dy}{dt}=f(t,y),\ \ \ a\leq t\leq b, \ \ \ \ y(a) = \alpha\ \ \mbox{and}\ y'(a) = \beta$$

For this system we have to provide both, the initial value $y(a)$ and the initial derivative $y'(a)$.

-

Now, let's define a new variable $w(t) = y'(t)$, the previous problem can be then written as

-\begin{align} -\frac{dy}{dt}=&w(t) \\ -\frac{dw}{dt}=&f(t,y)-g(t,y)w\, ,\ \ \ a\leq t\leq b\,, \ \ \ \ y(a) = \alpha\ \ \mbox{and}\ w(a) = \beta -\end{align}

Each of this problem has now the form required by the Euler's algorithm, and the solution can be computed as:

-\begin{align} -w_{i+1}=& w_{i} + [f(t_i,y_i)-g(t_i,y_i)w_i]\Delta t \\ -y_{i+1}=&y_i + w_i \Delta t\, ,\ \ \ a\leq t\leq b\,, \ \ \ \ y(a) = \alpha\ \ \mbox{and}\ w(a) = \beta -\end{align} -
-
-
-
- -
- -
-
-

Euler method for second order differential equations

We can define the column vectors -\begin{align} -\boldsymbol{U}=\begin{bmatrix} -U_1\\ -U_2\\ -\end{bmatrix}=&\begin{bmatrix} -y(t)\\ -w(t)\\ -\end{bmatrix}\,,& -\boldsymbol{V}(\boldsymbol{U},t)=\begin{bmatrix} -w(t)\\ -f(t,y)-g(t,y)w(t)\\ -\end{bmatrix}=&\begin{bmatrix} -U_2\\ -f(t,U_1)-g(t,U_1)U_2\\ -\end{bmatrix} -\end{align} -such that

- -
-
-
-
- -
- -
-
-

Newton's third law of motion

In fact, the equation of motion can be seen as the system of equations -\begin{align} -\frac{\boldsymbol{p}}{m}=&\frac{\operatorname{d}\boldsymbol{x}}{\operatorname{d}t}\\ -\boldsymbol{p}=& \gamma m \boldsymbol{v}\\ -\boldsymbol{F}=&\frac{\operatorname{d}\boldsymbol{p}}{\operatorname{d} t} -\end{align}

- -
-
-
-
- -
- -
-
-

Example:

- -

An object of 0.5 Kg is launched from the top of a building of 50 m with an horizontal speed of 5 m/s. Study the evolution of the movement

-
    -
  • Neglecting the air friction
  • -
- -
-
-
-
- -
- -
-
- -
-
-
import numpy as np
-import pandas as pd
-df=pd.DataFrame()
-m=.5
-g=9.8
-# intial conditions
-x=np.array([0,50,0])
-v=np.array([5,0,0])
-p=m*v
-deltat=0.01
-# Analysis for the first 3 s
-df=df.append({'x':x,'p':p},ignore_index=True)
-
-for t in np.arange( 0,3,deltat):
-    Fg=np.array([0,-m*g,0])
-    p=p+Fg*deltat
-    x=x+(p/m)*deltat
-    df=df.append({'x':x,'p':p},ignore_index=True)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
df#[:3]
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
px
0[2.5, 0.0, 0.0][0, 50, 0]
1[2.5, -0.049, 0.0][0.05, 49.99902, 0.0]
2[2.5, -0.098, 0.0][0.1, 49.997060000000005, 0.0]
3[2.5, -0.14700000000000002, 0.0][0.15000000000000002, 49.99412, 0.0]
4[2.5, -0.196, 0.0][0.2, 49.9902, 0.0]
5[2.5, -0.245, 0.0][0.25, 49.9853, 0.0]
6[2.5, -0.294, 0.0][0.3, 49.979420000000005, 0.0]
7[2.5, -0.34299999999999997, 0.0][0.35, 49.97256, 0.0]
8[2.5, -0.39199999999999996, 0.0][0.39999999999999997, 49.96472, 0.0]
9[2.5, -0.44099999999999995, 0.0][0.44999999999999996, 49.9559, 0.0]
10[2.5, -0.48999999999999994, 0.0][0.49999999999999994, 49.9461, 0.0]
11[2.5, -0.5389999999999999, 0.0][0.5499999999999999, 49.935320000000004, 0.0]
12[2.5, -0.588, 0.0][0.6, 49.92356, 0.0]
13[2.5, -0.637, 0.0][0.65, 49.91082, 0.0]
14[2.5, -0.686, 0.0][0.7000000000000001, 49.8971, 0.0]
15[2.5, -0.7350000000000001, 0.0][0.7500000000000001, 49.882400000000004, 0.0]
16[2.5, -0.7840000000000001, 0.0][0.8000000000000002, 49.86672, 0.0]
17[2.5, -0.8330000000000002, 0.0][0.8500000000000002, 49.85006, 0.0]
18[2.5, -0.8820000000000002, 0.0][0.9000000000000002, 49.83242, 0.0]
19[2.5, -0.9310000000000003, 0.0][0.9500000000000003, 49.8138, 0.0]
20[2.5, -0.9800000000000003, 0.0][1.0000000000000002, 49.794200000000004, 0.0]
21[2.5, -1.0290000000000004, 0.0][1.0500000000000003, 49.77362, 0.0]
22[2.5, -1.0780000000000003, 0.0][1.1000000000000003, 49.75206, 0.0]
23[2.5, -1.1270000000000002, 0.0][1.1500000000000004, 49.72952, 0.0]
24[2.5, -1.1760000000000002, 0.0][1.2000000000000004, 49.706, 0.0]
25[2.5, -1.225, 0.0][1.2500000000000004, 49.6815, 0.0]
26[2.5, -1.274, 0.0][1.3000000000000005, 49.65602, 0.0]
27[2.5, -1.323, 0.0][1.3500000000000005, 49.62956, 0.0]
28[2.5, -1.3719999999999999, 0.0][1.4000000000000006, 49.60212, 0.0]
29[2.5, -1.4209999999999998, 0.0][1.4500000000000006, 49.5737, 0.0]
.........
271[2.5, -13.278999999999971, 0.0][13.550000000000058, 13.88112000000001, 0.0]
272[2.5, -13.327999999999971, 0.0][13.600000000000058, 13.61456000000001, 0.0]
273[2.5, -13.37699999999997, 0.0][13.650000000000059, 13.347020000000011, 0.0]
274[2.5, -13.42599999999997, 0.0][13.70000000000006, 13.078500000000012, 0.0]
275[2.5, -13.47499999999997, 0.0][13.75000000000006, 12.809000000000013, 0.0]
276[2.5, -13.523999999999969, 0.0][13.800000000000061, 12.538520000000014, 0.0]
277[2.5, -13.572999999999968, 0.0][13.850000000000062, 12.267060000000015, 0.0]
278[2.5, -13.621999999999968, 0.0][13.900000000000063, 11.994620000000015, 0.0]
279[2.5, -13.670999999999967, 0.0][13.950000000000063, 11.721200000000016, 0.0]
280[2.5, -13.719999999999967, 0.0][14.000000000000064, 11.446800000000016, 0.0]
281[2.5, -13.768999999999966, 0.0][14.050000000000065, 11.171420000000015, 0.0]
282[2.5, -13.817999999999966, 0.0][14.100000000000065, 10.895060000000017, 0.0]
283[2.5, -13.866999999999965, 0.0][14.150000000000066, 10.617720000000018, 0.0]
284[2.5, -13.915999999999965, 0.0][14.200000000000067, 10.339400000000019, 0.0]
285[2.5, -13.964999999999964, 0.0][14.250000000000068, 10.06010000000002, 0.0]
286[2.5, -14.013999999999964, 0.0][14.300000000000068, 9.77982000000002, 0.0]
287[2.5, -14.062999999999963, 0.0][14.350000000000069, 9.49856000000002, 0.0]
288[2.5, -14.111999999999963, 0.0][14.40000000000007, 9.216320000000021, 0.0]
289[2.5, -14.160999999999962, 0.0][14.45000000000007, 8.933100000000021, 0.0]
290[2.5, -14.209999999999962, 0.0][14.500000000000071, 8.648900000000022, 0.0]
291[2.5, -14.258999999999961, 0.0][14.550000000000072, 8.363720000000024, 0.0]
292[2.5, -14.30799999999996, 0.0][14.600000000000072, 8.077560000000025, 0.0]
293[2.5, -14.35699999999996, 0.0][14.650000000000073, 7.790420000000026, 0.0]
294[2.5, -14.40599999999996, 0.0][14.700000000000074, 7.502300000000027, 0.0]
295[2.5, -14.45499999999996, 0.0][14.750000000000075, 7.213200000000027, 0.0]
296[2.5, -14.503999999999959, 0.0][14.800000000000075, 6.923120000000028, 0.0]
297[2.5, -14.552999999999958, 0.0][14.850000000000076, 6.632060000000029, 0.0]
298[2.5, -14.601999999999958, 0.0][14.900000000000077, 6.34002000000003, 0.0]
299[2.5, -14.650999999999957, 0.0][14.950000000000077, 6.047000000000031, 0.0]
300[2.5, -14.699999999999957, 0.0][15.000000000000078, 5.753000000000032, 0.0]
-

301 rows × 2 columns

-
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
df.to_json('mvto.json')
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
#pd.read_json('mvto.json').x.str[1]
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
#py=df.p.str[1]
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
#               x       y
-plt.plot(df.x.str[0],df.x.str[1])
-plt.xlabel('$x$ [m]',size=15)
-plt.ylabel('$y$ [m]',size=15)
-plt.grid()
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Consider now the case the movement inside a fluid with a draggin force proportinal to the velocity -$$ -\boldsymbol{F}_D=c \boldsymbol{v} = c \frac{\boldsymbol{p}}{m}\,, -$$ -where $c$ can take the values 0 (not dragging force), 0.1 y 0.5

- -
-
-
-
- -
- -
-
- -
-
-
import numpy as np
-import pandas as pd
-df=pd.DataFrame()
-m=.5
-g=9.8
-for c in [0,0.1,0.5]:
-    x=np.array([0,50,0])
-    v=np.array([5,0,0])
-    p=m*v
-    deltat=0.01
-    t=0
-    df=df.append({'x':x,'p':p,'t':t,'c':c},ignore_index=True)
-    
-    for t in np.arange( 0,3,deltat):
-        Fg=np.array([0,-m*g,0])-c*(p/m)
-        p=p+Fg*deltat
-        x=x+(p/m)*deltat
-        t=t+deltat
-        df=df.append({'x':x,'p':p,'t':t,'c':c},ignore_index=True)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
df.c.unique()
-
- -
-
-
- -
-
- -
-
- - - -
-
array([0. , 0.1, 0.5])
-
- -
-
-
-
- -
-
- -
- -
-
-

Apply a mask upon the DataFrame:

-
    -
  • Example
  • -
- -
-
-
-
- -
- -
-
- -
-
-
df[np.logical_or( df.c==0,df.c==0.5  )].c.unique()
-
- -
-
-
- -
-
- -
-
- - - -
-
array([0. , 0.5])
-
- -
-
-
-
- -
-
- -
- -
-
-
    -
  • Filter c==0
  • -
- -
-
-
-
- -
- -
-
- -
-
-
df[df.c==0][:3]
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
cptx
00.0[2.5, 0.0, 0.0]0.00[0, 50, 0]
10.0[2.5, -0.049, 0.0]0.01[0.05, 49.99902, 0.0]
20.0[2.5, -0.098, 0.0]0.02[0.1, 49.997060000000005, 0.0]
-
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
df[df.c==0.5][:3]
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
cptx
6020.5[2.5, 0.0, 0.0]0.00[0, 50, 0]
6030.5[2.475, -0.049, 0.0]0.01[0.0495, 49.99902, 0.0]
6040.5[2.45025, -0.09751, 0.0]0.02[0.09850500000000001, 49.9970698, 0.0]
-
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
from mpl_toolkits.mplot3d import Axes3D
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
fig = plt.figure()
-ax = fig.gca(projection='3d')
-c=0
-ax.plot(df[df.c==c].x.str[0].values, df[df.c==c].x.str[1].values, df[df.c==c].x.str[2].values)
-c=0.1
-ax.plot(df[df.c==c].x.str[0].values, df[df.c==c].x.str[1].values, df[df.c==c].x.str[2].values)
-c=0.5
-ax.plot(df[df.c==c].x.str[0].values, df[df.c==c].x.str[1].values, df[df.c==c].x.str[2].values)
-
-ax.view_init(80, 250)
-plt.xlabel('$x$ [m]',size=10)
-plt.ylabel('$y$ [m]',size=10)
-
- -
-
-
- -
-
- -
-
- - - -
-
Text(0.5, 0, '$y$ [m]')
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
c=0
-plt.plot(df[df.c==c].x.str[0], df[df.c==c].x.str[1])
-c=0.1
-plt.plot(df[df.c==c].x.str[0], df[df.c==c].x.str[1])
-c=0.5
-plt.plot(df[df.c==c].x.str[0], df[df.c==c].x.str[1])
-plt.xlabel('$x$ [m]',size=15)
-plt.ylabel('$y$ [m]',size=15)
-plt.grid()
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Activity: Find the time to reach the position y=0 in each case. By using an algorithm to find roots

- -
-
-
-
- -
- -
-
-

Activity: Repeat the previous analysis for a baseball in the air with a dragging force proportinal to the square of the velocity. The diameter of the baseball is 7.5cm

- -
-
-
-
- -
- -
-
-

Example. Spring

In order to apply this, let's assume a simple mass-spring.

-

-

The equation of motion according to Newton's second law is

-$$ F = -kx $$

Using the previous results, we can rewrite this as:

-$$ \frac{d p}{dt} = -k x $$$$ \frac{dx}{dt} = \frac{p}{m}$$

And the equivalent Euler system is -\begin{align} -v_{i+1}=& v_{i} - \Delta t\frac{k}{m}x_i \\ -x_{i+1}=&x_i + v_i \Delta t\, ,\ \ \ x(0) = x_0\ \ \mbox{and}\ v(0) = v_0 -\end{align}

- -
-
-
-
- -
- -
-
-

**Activity**

-
-
-
-
- -
- -
-
-

-**1.** Using the initial conditions $x(0) = 0$ and $v(0) = 3$, solve the previous system. Plot the solutions $x(t)$ and $y(t)$ and compare with real solutions. Furthermore, calculate the total energy of the system. What can you conclude about the behaviour of the energy? Does it make any sense? -

- -
-
-
-
- -
- -
-
-

-**2.** Using the same reasoning, derive the equations for a simple pendulum. Compare the solution for small oscillations with the analytic one. What happens when increasing the initial amplitude of the movement? -

- -
-
-
-
- -
- -
-
-
- -
-
-
-
- -
- -
-
-

Implementation in Scipy

-
-
-
-
- -
- -
-
- -
-
-
import scipy.integrate as integrate
-
- -
-
-
- -
-
- -
- -
-
-

First order ordinary differential equations

integrate.odeint: -Integrate a system of ordinary differential equations

-

Uso básico

-
integrate.odeint(func,y0,t)
-
-

Solves the initial value problem for stiff or non-stiff systems -of first order ordinary differential equations: -$$ -\frac{dy}{dt}=f(y,t) -$$ -where $y$ can be a vector.

- -
-
-
-
- -
- -
-
-

Example

Consider the following differential equation -$$ \frac{dy(t)}{dt}=-k y(t),$$ -where $k$ is constant

- -
-
-
-
- -
- -
-
- -
-
-
def dy_dt(y,t):
-    k = 0.3
-    dydt = -k * y
-    return dydt
-
- -
-
-
- -
-
- -
- -
-
-

For a first evolution after one step of $\Delta t=0.1$: con condición inicial $y(0)=y_0=5$

- -
-
-
-
- -
- -
-
- -
-
-
# initial condition
-y0 = 5
-t=[0,0.1]
-integrate.odeint(dy_dt,y0,t)
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[5.        ],
-       [4.85222774]])
-
- -
-
-
-
- -
-
- -
- -
-
-

while the evolution from 0 to 20 s is

- -
-
-
-
- -
- -
-
- -
-
-
# time points
-t = np.linspace(0,20)
-
-# solve ODE
-y = integrate.odeint(dy_dt,y0,t)
-
-# plot results
-plt.plot(t,y)
-plt.xlabel('t',size=15)
-plt.ylabel('y(t)',size=15)
-plt.grid()
-plt.show()
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Compare with the analytical solution $$y(t)=y_0\operatorname{e}^{-kt}$$

- -
-
-
-
- -
- -
-
- -
-
-
# time points
-t = np.linspace(0,20)
-
-#k = 0.3 solve ODE
-y0=5
-y = integrate.odeint(dy_dt,y0,t)
-
-k=0.3
-# plot results
-plt.plot(t,y,'c-')
-plt.xlabel('t',size=15)
-plt.plot(t,y0*np.exp(-k*t),'k:')
-plt.xlabel('t',size=15)
-plt.ylabel('y(t)',size=15)
-plt.grid()
-plt.show()
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Second order differential equations

-
-
-
-
- -
- -
-
-

Although first-order schemes like Euler's method are illustrative and allow a good understanding of the numerical problem, real applications cannot be dealt with them, instead more precise and accurate high-order methods must be invoked. In this section we shall cover a well-known family of numerical integrators, the Runge-Kutta methods.

- -
-
-
-
- -
- -
-
- -
-
-
import scipy.integrate as integrate
-
- -
-
-
- -
-
- - - -
- -
-
-

Example: From http://sam-dolan.staff.shef.ac.uk/mas212/

-

As explained before, we need to write a second order ordinary differential equations in terms of first order matricial ordinary differential equation. In terms of a parameter, $x$, this implay to have a column vector -$$ -U=\begin{bmatrix} -y\\ -z\\ -\end{bmatrix} -$$4 -$$ -\frac{dU}{dt}=V(U,t). -$$

- -
-
-
-
- -
- -
-
-

Suppose we have a second-order ODE such as a damped simple harmonic motion equation, -$$ -\quad y'' + 2 y' + 2 y = \cos(2x), \quad \quad y(0) = 0, \; y'(0) = 0 -$$ -We can turn this into two first-order equations by defining a new depedent variable. For example, -$$ -\quad z \equiv y' \quad \Rightarrow \quad z' + 2 z + 2y = \cos(2x), \quad z(0)=y(0) = 0. -$$ -So that -$$ -y'=z \quad \Rightarrow \quad z' =- 2 z - 2y + \cos(2x), \quad z(0)=y(0) = 0. -$$ -where -$$ -\frac{dU}{dx}=\begin{bmatrix}y'\\z'\end{bmatrix} -$$ -We can solve this system of ODEs using "odeint" with lists, as follows:

- -
-
-
-
- -
- -
-
-

Let -$$ -U=\begin{bmatrix} -U_0\\ -U_1 -\end{bmatrix}=\begin{bmatrix} -y\\ -z -\end{bmatrix}. -$$ -Therefore -\begin{align} -\frac{\operatorname{d}}{\operatorname{d} x} -\begin{bmatrix} -y\\ -z\\ -\end{bmatrix}=& -\begin{bmatrix} -z\\ --2z-2y+\cos(2x)\\ -\end{bmatrix}\\ -\frac{\operatorname{d}}{\operatorname{d} x} -U=& -\begin{bmatrix} -U_1\\ --2U_1-2U_0+\cos(2x)\\ -\end{bmatrix} -\end{align}

- -
-
-
-
- -
- -
-
-

Implementation by using only $U$

- -
-
-
-
- -
- -
-
- -
-
-
def dU_dx(U, x):
-    '''
-    Here U is a vector such that y=U[0] and z=U[1]. 
-    This function should return [y', z']
-    '''    
-    return [      U[1], 
-            -2*U[1] - 2*U[0] + np.cos(2*x)]
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
U0 # → x=0
-
- -
-
-
- -
-
- -
-
- - - -
-
[0, 0]
-
- -
-
-
-
- -
-
- -
- -
-
-

x→0.1

- -
-
-
-
- -
- -
-
- -
-
-
integrate.odeint(dU_dx, U0, [0,0.1])
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[0.        , 0.        ],
-       [0.00465902, 0.08970031]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
array(
-        [[0.        , 0.         ],#→ U(0)
-         [0.00465902, 0.08970031]] #→ U(0.1)=[y(0.1),y'(0.1)]
-     )
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[0.        , 0.        ],
-       [0.00465902, 0.08970031]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
Us[:3]
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[0.        , 0.        ],
-       [0.02601336, 0.1841925 ],
-       [0.08083294, 0.229454  ]])
-
- -
-
-
-
- -
-
- -
- -
-
-

Note that y=Us[:,0]

- -
-
-
-
- -
- -
-
- -
-
-
U0 = [0, 
-      0]
-xs = np.linspace(0, 50, 200)
-Us = integrate.odeint(dU_dx, U0, xs)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
Us[:3]
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[0.        , 0.        ],
-       [0.02601336, 0.1841925 ],
-       [0.08083294, 0.229454  ]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
Us[:,0][:3]
-
- -
-
-
- -
-
- -
-
- - - -
-
array([0.        , 0.02601336, 0.08083294])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
ys = Us[:,0] #First column is extracted
-
-plt.xlabel("x")
-plt.ylabel("y")
-plt.title("Damped harmonic oscillator")
-plt.plot(xs,ys);
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
zs = Us[:,1]
-
-plt.xlabel("x")
-plt.ylabel("z")
-plt.title("Damped harmonic oscillator")
-plt.plot(xs,zs);
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Implementation by using explicitly $y(x)$ and $z(x)$ -\begin{align} -\frac{\operatorname{d}}{\operatorname{d} x} -\begin{bmatrix} -y\\ -z\\ -\end{bmatrix}=& -\begin{bmatrix} -z\\ --2z-2y+\cos(2x)\\ -\end{bmatrix} -\end{align}

- -
-
-
-
- -
- -
-
- -
-
-
def dU_dx(U, x):
-    '''
-    Here U is a vector such that y=U[0] and z=U[1]. 
-    This function should return [y', z']
-    '''    
-    y,z=U # y → U[0]; z → U[1] 
-    return [        z, 
-            -2*z - 2*y + np.cos(2*x)]
-
-U0 = [0, 0]
-xs = np.linspace(0, 50, 200)
-Us = integrate.odeint(dU_dx, U0, xs)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
ys = Us[:,0]
-
-plt.xlabel("x")
-plt.ylabel("y")
-plt.title("Damped harmonic oscillator")
-plt.plot(xs,ys);
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Activity: Apply the previous example to the problem of parabolic motion with air friction:

- -
-
-
-
- -
- -
-
-\begin{align} -\frac{\boldsymbol{p}}{m}=&\frac{\operatorname{d}\boldsymbol{x}}{\operatorname{d}t}\\ -\boldsymbol{F}=&\frac{\operatorname{d}\boldsymbol{p}}{\operatorname{d} t} -\end{align}\begin{align} -\frac{\operatorname{d}}{\operatorname{d} t} -\begin{bmatrix} - \boldsymbol{x}\\ - \boldsymbol{p}\\ -\end{bmatrix}=& -\begin{bmatrix} -\boldsymbol{p}/m\\ --m\boldsymbol{g}-c \boldsymbol{p}/m \\ -\end{bmatrix}\,, -\end{align}

such that in two dimensions

- -
-
-
-
- -
- -
-
-$$ -\boldsymbol{U}=\begin{bmatrix} -{U}_0\\ -{U}_1\\ -{U}_2\\ -{U}_3\\ -\end{bmatrix}=\begin{bmatrix} -{x}\\ -y\\ -p_x\\ -p_y\\ -\end{bmatrix} -$$\begin{align} -\frac{\operatorname{d}}{\operatorname{d} t} \boldsymbol{U}=& -\begin{bmatrix} -{U}_2/m\\ -{U}_3/m\\ --c{U}_2/m\\ --m{g}-c{U}_3/m\\ -\end{bmatrix} -\end{align} -
-
-
-
- -
- -
-
- -
-
-
def dU_dt(U, t,c=0.,m=.5,g=9.8):
-    '''
-    Here U is a vector such that y=U[0] and z=U[1]. 
-    This function should return [y', z']
-    '''
-    return [U[2]/m,
-            U[3]/m,
-            -c*U[2]/m, 
-            -m*g-c*U[3]/m]
-
-m=0.5
-# p_x(0)=5*m → v(0)=5 m/s
-U0 = [0, 50,m*5,0]
-t = np.linspace(0, 3, 200)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
isinstance((0.1),float)
-
- -
-
-
- -
-
- -
-
- - - -
-
True
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
isinstance((0.1,),tuple)
-
- -
-
-
- -
-
- -
-
- - - -
-
True
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
Us = integrate.odeint(dU_dt, U0, t )  
-xs = Us[:,0]
-ys = Us[:,1]
-plt.plot(xs,ys)
-Us = integrate.odeint(dU_dt, U0, t,args=(0.1,) )  
-xs = Us[:,0]
-ys = Us[:,1]
-plt.plot(xs,ys)
-Us = integrate.odeint(dU_dt, U0, t,args=(0.5,) )  
-xs = Us[:,0]
-ys = Us[:,1]
-plt.plot(xs,ys)
-plt.xlabel('$x$ [m]',size=15)
-plt.ylabel('$y$ [m]',size=15)
-
- -
-
-
- -
-
- -
-
- - - -
-
Text(0, 0.5, '$y$ [m]')
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Activity: Implemet directly: -\begin{align} -\frac{\operatorname{d}}{\operatorname{d} t} -\begin{bmatrix} - \boldsymbol{x}\\ - \boldsymbol{p}\\ -\end{bmatrix}=& -\begin{bmatrix} -\boldsymbol{p}/m\\ --m\boldsymbol{g}-c \boldsymbol{p}/m \\ -\end{bmatrix}\,, -\end{align} -as -\begin{align} -\frac{\operatorname{d}}{\operatorname{d} t} -\begin{bmatrix} - x\\ - y\\ - p_x\\ - p_y -\end{bmatrix}=& -\begin{bmatrix} -p_x/m\\ -p_y/m\\ --c p_x/m \\ --mg-c p_y/m \\ -\end{bmatrix}\,, -\end{align}

- -
-
-
-
- -
- -
-
- -
-
-
def dU_dt(U, t,c=0.,m=.5,g=9.8):
-    '''
-    Here U is a vector such that y=U[0] and z=U[1]. 
-    This function should return [y', z']
-    '''
-    x,y,px,py=U
-    return [px/m,
-            py/m,
-            -c*px/m, 
-            -m*g-c*py/m]
-
-m=0.5
-U0 = [0, 50,5*m,0]
-t = np.linspace(0, 3, 200)
-
-Us = integrate.odeint(dU_dt, U0, t,args=(0.5,) )  
-xs = Us[:,0]
-ys = Us[:,1]
-plt.plot(xs,ys)
-
- -
-
-
- -
-
- -
-
- - - -
-
[<matplotlib.lines.Line2D at 0x7f60f36e3128>]
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
%pylab inline
-
- -
-
-
- -
-
- -
-
- -
-
Populating the interactive namespace from numpy and matplotlib
-
-
-
-
-
-
- -
-
- -
- -
-
-

Example 2

-
-
-
-
- -
- -
-
-

In this example we are going to use the Scipy implementation for mapping the phase space of a pendulum.

-

The equations of the pendulum are given by:

-$$ \frac{d\theta}{dt} = \omega $$$$ \frac{d\omega}{dt} = -\frac{g}{l}\sin \theta $$\begin{align} -\frac{d}{dt} U=\begin{pmatrix}\omega\\ - -\dfrac{g}{l}\sin\theta \end{pmatrix}, -\end{align}

where -\begin{align} - U=\begin{pmatrix}\theta\\ -\omega \end{pmatrix}. -\end{align}

- -
-
-
-
- -
- -
-
- -
-
-
from scipy import integrate
-def dU_dt(U, t,l=1,g=9.8):
-    '''
-    Here U is a vector such that   θ=U[0] and ω=U[1]. 
-    This function should return [θ', ω']
-    '''    
-    θ,ω=U
-    return [ω, -g/l*np.sin( θ ) ]
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
tmax = 6*np.pi
-omega_max = 8 #rad/s
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
Nic = 1000
-#Maxim angular velocity
-
-theta0s = np.random.uniform(-4*np.pi,4*np.pi,Nic)
-omega0s = np.random.uniform(-omega_max,omega_max,Nic)
-
- -
-
-
- -
-
- -
- -
-
-

TAREA: Generar un rango aleatorio uniforme de varios ordenes de magnitud. -En particular, 1000 números aleatorios entre $3\times 10^{-6}$ hasta $5\times 10^{4}$

- -
-
-
-
- -
- -
-
- -
-
-
U0=[theta0s[0],omega0s[0]]
-U0
-
- -
-
-
- -
-
- -
-
- - - -
-
[-1.094232903981899, -2.8722875660380076]
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
t=np.linspace(0,tmax,400)
-Us=integrate.odeint(dU_dt,U0,t)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
plt.plot(Us[:,0],Us[:,1],lw = 1, color = "black" )
-plt.xlim(-8,8)
-plt.ylim(-10,10)
-plt.xlabel(r'$\theta$ [rad]',size=15)
-plt.ylabel(r'$\omega$ [rad/s]',size=15)
-
- -
-
-
- -
-
- -
-
- - - -
-
Text(0, 0.5, '$\\omega$ [rad/s]')
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
list( zip([1,2],[3,4]) )
-
- -
-
-
- -
-
- -
-
- - - -
-
[(1, 3), (2, 4)]
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
j=0
-plt.figure( figsize = (8,5) )
-for theta0, omega0 in zip(theta0s, omega0s):
-    t=np.linspace(0,tmax,400)
-    U0=[theta0,omega0]
-    Us=integrate.odeint(dU_dt,U0,t)
-    plt.plot(Us[:,0]/np.pi,Us[:,1],lw = 0.1, color = "black" )
-    if j==Nic: #secutity stop
-        break
-    j=j+1
-    
-#Format of figure
-plt.xlabel( "$\\theta/\pi$", fontsize = 18 )
-plt.ylabel( "$\omega$ [rad/s]", fontsize = 18 )
-plt.xlim( (-3, 3) )
-plt.ylim( (-omega_max, omega_max) )
-plt.title( "Phase space of a pendulum" )
-plt.grid(1)    
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

The nearly closed curves around (0,0) represent the regular small swings of the pendulum near its -rest position. The oscillatory curves up and down of the closed curves represent the movement when the pendulum start at $\theta=0$ but with high enough angular speed such that the pendulum goes all the way around. Of course, its -angular speed will slow down on the way up but then it will speed up on the way down again. -In the absence of friction, it just keeps spinning around indefinitely. The counterclockwise -motions of the pendulum of this kind are shown in the graph by the wavy lines -at the top with positive angular speed, while the curves on the bottom -which go from right to left represent clockwise rotations. The phase space have a periodicity of $2\pi$.

- -
-
-
-
- -
- -
-
-

Small oscillation

- -
-
-
-
- -
- -
-
- -
-
-
t=np.linspace(0,tmax,400)
-Us=integrate.odeint(dU_dt,[0,2],t)
-plt.plot(Us[:,0],Us[:,1],lw = 1, color = "black" )
-plt.xlim(-8,8)
-plt.ylim(-10,10)
-
- -
-
-
- -
-
- -
-
- - - -
-
(-10.0, 10.0)
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

All around

- -
-
-
-
- -
- -
-
- -
-
-
t=np.linspace(0,tmax,400)
-Us=integrate.odeint(dU_dt,[0,7],t)
-plt.plot(Us[:,0],Us[:,1],lw = 1, color = "black" )
-plt.xlim(-8,8)
-plt.ylim(-10,10)
-
- -
-
-
- -
-
- -
-
- - - -
-
(-10.0, 10.0)
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
t=np.linspace(0,tmax,400)
-Us=integrate.odeint(dU_dt,[0,-7],t)
-plt.plot(Us[:,0],Us[:,1],lw = 1, color = "black" )
-plt.xlim(-8,8)
-plt.ylim(-10,10)
-
- -
-
-
- -
-
- -
-
- - - -
-
(-10.0, 10.0)
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
plt.plot(Us[:,0],Us[:,1],lw = 1, color = "black" )
-plt.xlim(-8,8)
-plt.ylim(-10,10)
-
- -
-
-
- -
-
- -
-
- - - -
-
(-10.0, 10.0)
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Activity: Check the anlytical expression for the period of a pendulum

- -
-
-
-
- -
- -
-
-
-

Appendix

-
-
-
-
- -
- -
-
-

**Activity**

-
-
-
-
- -
- -
-
-

-Using the previous example, explore the phase space of a simple oscillator and a damped pendulum. -

- -
-
-
-
- -
- -
-
-

Fourth-order Runge-Kutta method

-
-
-
-
- -
- -
-
-

Finally, the most used general purpose method is the fourth-order Runge-Kutta scheme. Its derivation follows the same previous reasoning, however the procedure is rather long and it makes no sense to reprouce it here. Instead, we will give the direct algorithm:

-

Let's assume again a problem of the form:

-$$ \frac{dy}{dt}=y'=f(t,y),\ \ \ a\leq t\leq b, \ \ \ \ y(a) = \alpha $$

The Runge-Kutta-4 (RK4) method allows us to predict the solution at the time $t+h$ as:

-$$ y(t+h) = y(t) + \frac{1}{6}( \mathbf{K}_0 + 2\mathbf{K}_1 + 2\mathbf{K}_2 + \mathbf{K}_3 ) $$

where:

-$$ \mathbf{K}_0 = hf(t,y)$$$$ \mathbf{K}_1 = hf\left( t + \frac{h}{2},y + \frac{\mathbf{K}_0}{2}\right)$$$$ \mathbf{K}_2 = hf\left( t + \frac{h}{2},y + \frac{\mathbf{K}_1}{2}\right)$$$$ \mathbf{K}_3 = hf\left( t + h,y + \mathbf{K}_2\right)$$ -
-
-
-
- -
- -
-
-

**Activity**

-
-
-
-
- -
- -
-
-


-The Lorenz attractor is a common set of differential equations of some models of terrestrial atmosphere studies. It is historically known as one of the first system to exhibit deterministic caos. The equations are:

-$$ \frac{dx}{dt} = a(y-x) $$$$ \frac{dy}{dt} = x(b-z)-y $$$$ \frac{dz}{dt} = xy-cz $$

with $a = 10$, $b=28$ and $c = 8/3$ the solution shows periodic orbits. -</font>

- -
-
-
-
- -
- -
-
-

-Write a routine that gives a step of RK4 and integrate the previous system. Plot the resulting 3D solution $(x,y,z)$. -

- -
-
-
-
- -
- -
-
-

Second-order Runge-Kutta methods

For this method, let's assume a problem of the form:

-$$ \frac{dy}{dt}=y'=f(t,y),\ \ \ a\leq t\leq b, \ \ \ \ y(a) = \alpha $$

Now, we want to know the solution in the next timestep, i.e. $y(t+h)$. For this, we propose the next solution:

-$$ y(t+h) = y(t) + c_0 f(t,y)h + c_1f[ t+ph, y+qhf(t,y) ]h $$

determining the coefficients $c_0, c_1, q$ and $p$, we will have the complete approximated solution of the problem.

-

One way to determine them is by comparing with the taylor expansion around $t$

-$$ y(t+h) = y(t) + f(t,y)h + \frac{1}{2}\left( \frac{\partial f}{\partial t} + \frac{\partial f}{\partial y} \right)h^2 + \mathcal{O}(h^3) $$

Now, we can also expand the function $f[ t+ph, y+qhf(t,y) ]$ around the point $(t,y)$, yielding:

-$$ f[ t+ph, y+qhf(t,y) ] = f(t,y) + \frac{\partial f}{\partial t}ph + \frac{\partial f}{\partial y}qh + \mathcal{O}(h^2) $$

Replacing this into the original expression:

-$$ y(t+h) = y(t) + c_0 f(t,y)h + c_1\left[ f(t,y) + \frac{\partial f}{\partial t}ph + \frac{\partial f}{\partial y}qh \right]h + \mathcal{O}(h^3)$$

ordering the terms we obtain:

-$$ y(t+h) = y(t) + (c_0+c_1) f(t,y)h + c_1\left[ \frac{\partial f}{\partial t}p + \frac{\partial f}{\partial y}q \right]h^2 + \mathcal{O}(h^3)$$

Equalling the next conditions are obtained:

-$$ c_0 + c_1 =1 \ \ \ c_1p=\frac{1}{2}\ \ \ c_1q = \frac{1}{2} $$

This set of equations are undetermined so there are several solutions, each one yielding a different method:

-$$ \matrix{ -c_0 = 0 & c_1=1 & p = 1/2 & q = 1/2 & \mbox{Modified Euler's Method} \\ -c_0 = 1/2 & c_1=1/2 & p = 1 & q = 1 & \mbox{Heun's Method} \\ -c_0 = 1/3 & c_1=2/3 & p = 3/4 & q = 3/4 & \mbox{Ralston's Method} -} $$

The algorithm is then:

-$$ y(t+h) = y(t) + (c_1+c_2)\mathbf{K}_1 $$

with

-$$ \mathbf{K}_1 = hf( t+pt, y+q\mathbf{K}_0 ) $$$$ \mathbf{K}_0 = hf(t,y) $$

All these methods constitute the second-order Runge-Kutta methods.

- -
-
-
-
- -
- -
-
-

Two-Point Boundary Value Problems

-
-
-
-
- -
- -
-
-

Up to now we have solved initial value problems of the form:

-$$ \frac{dy}{dt}=y'=f(t,y),\ \ \ a\leq t\leq b, \ \ \ \ y(a) = \alpha $$

Second order equations can be similarly planted as

-$$ \frac{d^2y}{dt^2}=y''=f(t,y,y'),\ \ \ a\leq t\leq b, \ \ \ \ y(a) = \alpha \ \ \ y'(a) = u $$

This type of systems can be readily solved by defining the auxiliar variable $w = y'$, turning it into a first order system of equations.

-

Now, we shall solve two-point boundary problem, where we have two conditions on the solution $y(t)$ instead of having the function and its derivative at some initial point, i.e.

-$$ \frac{d^2y}{dt^2}=y''=f(t,y,y'),\ \ \ a\leq t\leq b, \ \ \ \ y(a) = \alpha \ \ \ y(b) = \beta $$

In spite of its similar form to the initial value problem, two-point boundary problems pose a increased difficulty for numerical methods. The main reason of this is the iterative procedure performed by numerical approaches, where from an initial point, further points are found. Trying to fit two different values at different points implies then a continuous readjusting of the solution.

-

A common way to solve these problems is by turning them into a initial-value problem

-$$ \frac{d^2y}{dt^2}=y''=f(t,y,y'),\ \ \ a\leq t\leq b, \ \ \ \ y(a) = \alpha \ \ \ y'(a) = u $$

Let's suppose some choice of $u$, integrating by using some of the previous methods, we obtain the final boundary condition $y(b)=\theta$. If the produced value is not the one we wanted from our initial problem, we try another value $u$. This can be repeated until we get a reasonable approach to $y(b)=\beta$. This method works fine, but it is so expensive and terribly inefficient.

-

Note when we change $u$, the final boundary value also change, so we can assume $y(b) = \theta$. The solution to the problem can be thought then as a root-finding problem:

-$$ y(b) = \theta(u) = \beta $$

or

-

$ r(u) \equiv \theta(u) - \beta = 0 $

-

where $r(u)$ is the residual function. This problem can be thus solved using some of the methods previously seen for the root-finding problem.

- -
-
-
-
- -
- -
-
-

Example 3

-
-
-
-
- -
- -
-
-

A very simplified model of interior solid planets consists of a set of spherically symmetric radial layers, where the next properties are computed: density $\rho(r)$, enclosed mass $m(r)$, gravity $g(r)$ and pressure $P(r)$. Each of these properties are assumed to be only radially dependent. The set of equations that rules the planetary interior is:

-

Hydrostatic equilibrium equation

-$$\frac{dP}{dr} = -\rho(r)g(r)$$

Adams-Williamson equation

-$$\frac{dg}{dr} = 4\pi G\rho(r) - \frac{2Gm(r)}{r^3}$$

Continuity equation

-$$\frac{dm}{dr} = 4\pi r^2 \rho(r)$$

Equation of state

-$$\frac{d\rho}{dr} = -\frac{\rho(r)^2g(r)}{K_s}$$

For accurate results the term $K_s$, called the adiabatic bulk modulus, is temperature and radii dependent. However, for the sake of simplicity we shall assume a constant value.

-

Solving simultaneously the previous set of equations, we can find the complete internal structure of a planet.

-

We have four functions to be determined and four equations, so the problem is solvable. It is only necessary to provide a set of boundary conditions of the form:

-$$ \rho(R) = \rho_{surf},\ \ \ m(R) = M_p, \ \ \ g(R) = g_{surf},\ \ \ P(R) = P_{atm} $$

where $R$ is the planetary radius, $\rho_{surf}$ the surface density, $M_p$ the mass of the planet, $g_{surf}$ the surface gravity and $P_{atm}$ the atmospheric pressure. However, there is a problem, we do not know the planetary radius $R$, so an extra condition is required to determine this value. This is reached through the physical condition $m(0) = 0$, this is, the enclosed mass at a radius $r = 0$ (center of the planet) must be 0.

-

The two-value boundary nature of this problem lies then in fitting the mass function at $m(R) = M_p$ and at $m(0) = 0$. To do so, let's call the residual mass $m(0) = M_r$. This value should depend on the chosen radius $R$, so a large value would imply a mass defect $M_r(R)<0$, and a small value a mass excess $M_r(0)>0$. The problem is then solving the radius $R$ for which $m(0) = M_r(R) = 0$. This can be done by using the bisection method.

- -
-
-
-
- -
- -
-
-

For this problem, we are going to assume an one-layer planet made of perovskite, so $K_s \approx 200\ GPa$. A planet mass equal to earth, so $M_p = 5.97219 \times 10^{24}\ kg$, a surface density $\rho_{surf} = 3500\ kg/m^3$ and a atmospheric pressure of $P_{atm} = 1\ atm = 1\times 10^5\ Pa$.

- -
-
-
-
- -
- -
-
-

Implementation of the pendulum phase space

-
-
-
-
- -
- -
-
- -
-
-
#RK2 integrator
-def RK2_step( f, y, t, h ):
-    #Creating solutions
-    K0 = h*f(t, y)
-    K1 = h*f(t + 0.5*h, y + 0.5*K0)
-    y1 = y + K1
-    #Returning solution
-    return y1
-
- -
-
-
- -
-
- -
- -
-
-

The phase space of a dynamical system is a space in which all the possible states of that system are univocally represented. For the case of the pendulum, a complete state of the system is given by the set $(\theta, \omega)$, so its phase space is two-dimensional. In order to explore all the possible states, we are going to generate a set of initial conditions and integrate them.

- -
-
-
-
- -
- -
-
- -
-
-
#========================================================
-#Defining parameters
-#========================================================
-#Gravity
-g = 9.8
-#Pendulum's lenght
-l = 1.0
-
-#Number of initial conditions
-Nic = 1000
-#Maxim angular velocity
-omega_max = 8
-
-#Maxim time of integration
-tmax = 6*np.pi
-#Timestep
-h = 0.01
-
-#========================================================
-#Dynamical function of the system
-#========================================================
-def function( t, y ):
-    #Using the convention y = [theta, omega]
-    theta = y[0]
-    omega = y[1]
-    #Derivatives
-    dtheta = omega
-    domega = -g/l*np.sin(theta)
-    return np.array([dtheta, domega])
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
#========================================================
-#Generating set of initial conditions
-#========================================================
-theta0s = -4*np.pi + np.random.random(Nic)*8*np.pi
-omega0s = -omega_max + np.random.random(Nic)*2*omega_max
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
#========================================================
-#Integrating and plotting the solution for each IC
-#========================================================
-#Setting figure
-plt.figure( figsize = (8,5) )
-jj=0
-for theta0, omega0 in zip(theta0s, omega0s):
-    #Arrays for solutions
-    time = [0,]
-    theta = [theta0,]
-    omega = [omega0,]
-    for i, t in zip(range(int(tmax/h)), np.arange( 0, tmax, h )):
-        #Building current condition
-        y = [theta[i], omega[i]]
-        #Integrating the system
-        thetai, omegai = RK2_step( function, y, t, h )
-        #Appending new components
-        theta.append( thetai )
-        omega.append( omegai )
-        time.append( t )
-        #if i==10:
-        #    break
-    #Plotting solution
-    plt.plot( theta, omega, lw=0.1, color = "blue" )
-    if jj==50:
-        break
-    jj=jj+1
-
-#Format of figure
-plt.xlabel( "$\\theta$", fontsize = 18 )
-plt.ylabel( "$\omega$", fontsize = 18 )
-plt.xlim( (-2*np.pi-2, 2*np.pi+2) )
-plt.ylim( (-omega_max-3, omega_max+3) )
-plt.title( "Phase space of a pendulum" )
-plt.grid(1)
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-
- -
-
-
-
- - - - -
- \ No newline at end of file diff --git a/_build/features/figures/Collage.png b/_build/features/figures/Collage.png deleted file mode 100644 index aed9424..0000000 Binary files a/_build/features/figures/Collage.png and /dev/null differ diff --git a/_build/features/figures/DUNE.jpg b/_build/features/figures/DUNE.jpg deleted file mode 100644 index 2901064..0000000 Binary files a/_build/features/figures/DUNE.jpg and /dev/null differ diff --git a/_build/features/figures/VPHphase.png b/_build/features/figures/VPHphase.png deleted file mode 100644 index 137b169..0000000 Binary files a/_build/features/figures/VPHphase.png and /dev/null differ diff --git a/_build/features/figures/adaptive_quadrature.png b/_build/features/figures/adaptive_quadrature.png deleted file mode 100644 index bb30f65..0000000 Binary files a/_build/features/figures/adaptive_quadrature.png and /dev/null differ diff --git a/_build/features/figures/circuit.png b/_build/features/figures/circuit.png deleted file mode 100644 index 2fb2b89..0000000 Binary files a/_build/features/figures/circuit.png and /dev/null differ diff --git a/_build/features/figures/datos.png b/_build/features/figures/datos.png deleted file mode 100644 index bdf21a6..0000000 Binary files a/_build/features/figures/datos.png and /dev/null differ diff --git a/_build/features/figures/example3_1-2.png b/_build/features/figures/example3_1-2.png deleted file mode 100644 index b9e4ab6..0000000 Binary files a/_build/features/figures/example3_1-2.png and /dev/null differ diff --git a/_build/features/figures/fp1.png b/_build/features/figures/fp1.png deleted file mode 100644 index 3902816..0000000 Binary files a/_build/features/figures/fp1.png and /dev/null differ diff --git a/_build/features/figures/fp3.png b/_build/features/figures/fp3.png deleted file mode 100644 index 5c9da26..0000000 Binary files a/_build/features/figures/fp3.png and /dev/null differ diff --git a/_build/features/figures/friction.svg b/_build/features/figures/friction.svg deleted file mode 100644 index b323cb4..0000000 --- a/_build/features/figures/friction.svg +++ /dev/null @@ -1,226 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/_build/features/figures/gitusage.png b/_build/features/figures/gitusage.png deleted file mode 100644 index 6a4853f..0000000 Binary files a/_build/features/figures/gitusage.png and /dev/null differ diff --git a/_build/features/figures/gitusage.svg b/_build/features/figures/gitusage.svg deleted file mode 100644 index b18064f..0000000 --- a/_build/features/figures/gitusage.svg +++ /dev/null @@ -1,942 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - Main repositoryLocal copy offorked repository - - - - { - $ git fetch upstream - - - $ git checkout master - upstream branchmaster branch - - $ git merge master - - Forked repository - $ git push origin master - - diff --git a/_build/features/figures/halos_bolshoi.png b/_build/features/figures/halos_bolshoi.png deleted file mode 100644 index 3e1f3c5..0000000 Binary files a/_build/features/figures/halos_bolshoi.png and /dev/null differ diff --git a/_build/features/figures/halosfraction.png b/_build/features/figures/halosfraction.png deleted file mode 100644 index b4a9f57..0000000 Binary files a/_build/features/figures/halosfraction.png and /dev/null differ diff --git a/_build/features/figures/leastaction.png b/_build/features/figures/leastaction.png deleted file mode 100644 index ff6cecf..0000000 Binary files a/_build/features/figures/leastaction.png and /dev/null differ diff --git a/_build/features/figures/leastaction.svg b/_build/features/figures/leastaction.svg deleted file mode 100644 index 1cd5ef7..0000000 --- a/_build/features/figures/leastaction.svg +++ /dev/null @@ -1,794 +0,0 @@ - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/_build/features/figures/leastaction1.svg b/_build/features/figures/leastaction1.svg deleted file mode 100644 index fb6b31e..0000000 --- a/_build/features/figures/leastaction1.svg +++ /dev/null @@ -1,620 +0,0 @@ - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/_build/features/figures/leastaction2.svg b/_build/features/figures/leastaction2.svg deleted file mode 100644 index badac9f..0000000 --- a/_build/features/figures/leastaction2.svg +++ /dev/null @@ -1,620 +0,0 @@ - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/_build/features/figures/leastaction3.svg b/_build/features/figures/leastaction3.svg deleted file mode 100644 index f1ed44b..0000000 --- a/_build/features/figures/leastaction3.svg +++ /dev/null @@ -1,793 +0,0 @@ - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/_build/features/figures/leastaction_pendulum.svg b/_build/features/figures/leastaction_pendulum.svg deleted file mode 100644 index 0423ca4..0000000 --- a/_build/features/figures/leastaction_pendulum.svg +++ /dev/null @@ -1,825 +0,0 @@ - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - θ( ) [rad] - - - - - - - diff --git a/_build/features/figures/lente1.png b/_build/features/figures/lente1.png deleted file mode 100644 index 04be6a2..0000000 Binary files a/_build/features/figures/lente1.png and /dev/null differ diff --git a/_build/features/figures/logic_gates.png b/_build/features/figures/logic_gates.png deleted file mode 100644 index 12714ab..0000000 Binary files a/_build/features/figures/logic_gates.png and /dev/null differ diff --git a/_build/features/figures/mass_spring.png b/_build/features/figures/mass_spring.png deleted file mode 100644 index cd0e61e..0000000 Binary files a/_build/features/figures/mass_spring.png and /dev/null differ diff --git a/_build/features/figures/mexicanhat.svg b/_build/features/figures/mexicanhat.svg deleted file mode 100644 index d9e9728..0000000 --- a/_build/features/figures/mexicanhat.svg +++ /dev/null @@ -1,4351 +0,0 @@ - - - - - - - image/svg+xml - - - - - Produced by GNUPLOT 4.2 patchlevel 4 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - H - G - - - - - - - - - - - - - - - - - - - - - diff --git a/_build/features/figures/nbviewer.png b/_build/features/figures/nbviewer.png deleted file mode 100644 index 0e42083..0000000 Binary files a/_build/features/figures/nbviewer.png and /dev/null differ diff --git a/_build/features/figures/nu.png b/_build/features/figures/nu.png deleted file mode 100644 index bf25e0c..0000000 Binary files a/_build/features/figures/nu.png and /dev/null differ diff --git a/_build/features/figures/pendulum.png b/_build/features/figures/pendulum.png deleted file mode 100644 index 496c324..0000000 Binary files a/_build/features/figures/pendulum.png and /dev/null differ diff --git a/_build/features/figures/radar.png b/_build/features/figures/radar.png deleted file mode 100644 index b4e5702..0000000 Binary files a/_build/features/figures/radar.png and /dev/null differ diff --git a/_build/features/figures/random1.png b/_build/features/figures/random1.png deleted file mode 100644 index 76f7b76..0000000 Binary files a/_build/features/figures/random1.png and /dev/null differ diff --git a/_build/features/figures/relation.jpg b/_build/features/figures/relation.jpg deleted file mode 100644 index a814ce5..0000000 Binary files a/_build/features/figures/relation.jpg and /dev/null differ diff --git a/_build/features/figures/relation.svg b/_build/features/figures/relation.svg deleted file mode 100644 index 3307dd9..0000000 --- a/_build/features/figures/relation.svg +++ /dev/null @@ -1,1562 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/_build/features/figures/simulation.png b/_build/features/figures/simulation.png deleted file mode 100644 index 421c624..0000000 Binary files a/_build/features/figures/simulation.png and /dev/null differ diff --git a/_build/features/figures/spring1.png b/_build/features/figures/spring1.png deleted file mode 100644 index d848d00..0000000 Binary files a/_build/features/figures/spring1.png and /dev/null differ diff --git a/_build/features/figures/table.png b/_build/features/figures/table.png deleted file mode 100644 index ab7ff78..0000000 Binary files a/_build/features/figures/table.png and /dev/null differ diff --git a/_build/features/figures/table_coefficients.png b/_build/features/figures/table_coefficients.png deleted file mode 100644 index dbeb2cc..0000000 Binary files a/_build/features/figures/table_coefficients.png and /dev/null differ diff --git a/_build/features/figures/voiddensity.png b/_build/features/figures/voiddensity.png deleted file mode 100644 index 58afb18..0000000 Binary files a/_build/features/figures/voiddensity.png and /dev/null differ diff --git a/_build/features/figures/voids.png b/_build/features/figures/voids.png deleted file mode 100644 index 3b9a165..0000000 Binary files a/_build/features/figures/voids.png and /dev/null differ diff --git a/_build/features/interpolation.html b/_build/features/interpolation.html deleted file mode 100644 index 656627b..0000000 --- a/_build/features/interpolation.html +++ /dev/null @@ -1,5679 +0,0 @@ ---- -interact_link: content/features/interpolation.ipynb -kernel_name: python3 -kernel_path: content/features -has_widgets: false -title: |- - Interpolation -pagenum: 11 -prev_page: - url: /features/one-variable-equations-fixed-point.html -next_page: - url: /features/LagrangePoly.html -suffix: .ipynb -search: x xi frac y f interpolation n polynomial t right plt left l m function points yi linear xm com polynomials p smallmatrix lagrange example end degree plot b ipynb numpy begin np text prod colab error font where pn leq google data activity roots align set such xn df max xj github www steps define de e neq master es implementation cdot color te value interval using both fit research restrepo computationalmethods blob discrete drive math derivation print org given details s polinomio defined kind cdots en wikipedia blue matter material methods however pdf br lp divided differences object - -comment: "***PROGRAMMATICALLY GENERATED, DO NOT EDIT. SEE ORIGINAL FILES IN /content***" ---- - -
-
Interpolation
-
-
- -
-
-

Open In Colab

- -
-
-
-
- -
- -
-
-

Interpolation Methods

Open In Colab

- -
-
-
-
- -
- -
-
-

Due to the discrete, and sometimes sparse, nature of experiments and observations, data taking procedures will always produce discrete data as well. Even, as we have seen before, information only can be discretely presented into a computer due to the binary representation. However, when we are dealing with physical models, continuous and smooth properties are of course preferred. Interpolation techniques allow then to recover a continuous field from sparse datasets. Throughout this section we shall cover some of these interpolation methods.

-
-

-

Bibliography:

[1a] Gonzalo Galiano Casas, Esperanza García Gonzalo Numerical Computation - GD - Web page with notebooks
-[1g] Mo Mu, MATH 3311: Introduction to Numerical Methods GD - Demostration Error in Lagrange Polynomials
-[1h] Zhiliang Xu, ACMS 40390: Fall 2016 - Numerical Analysis GD</br>

-

https://github.com/restrepo/Calculus/blob/master/Differential_Calculus.ipynb

- -
-
-
-
- - - -
- -
-
- -
-
-
%pylab inline
-
- -
-
-
- -
-
- -
-
- -
-
Populating the interactive namespace from numpy and matplotlib
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
from IPython.display import display, Markdown, Latex, Image 
-import pandas as pd
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
from scipy import interpolate
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
import numpy as np
-# JSAnimation import available at https://github.com/jakevdp/JSAnimation
-#from JSAnimation import IPython_display
-from matplotlib import animation
-from IPython.core.display import Image 
-
- -
-
-
- -
-
- -
- -
-
-

Pretty print inside colaboratory

- -
-
-
-
- -
- -
-
- -
-
-
import IPython
-
-def setup_typeset():
-  """MathJax initialization for the current cell.
-  
-  This installs and configures MathJax for the current output.
-  """
-  IPython.display.display(IPython.display.HTML('''
-      <script src="https://www.gstatic.com/external_hosted/mathjax/latest/MathJax.js?config=TeX-AMS_HTML-full,Safe&delayStartupUntil=configured"></script>
-      <script>
-        (() => {
-          const mathjax = window.MathJax;
-          mathjax.Hub.Config({
-          'tex2jax': {
-            'inlineMath': [['$', '$'], ['\\(', '\\)']],
-            'displayMath': [['$$', '$$'], ['\\[', '\\]']],
-            'processEscapes': true,
-            'processEnvironments': true,
-            'skipTags': ['script', 'noscript', 'style', 'textarea', 'code'],
-            'displayAlign': 'center',
-          },
-          'HTML-CSS': {
-            'styles': {'.MathJax_Display': {'margin': 0}},
-            'linebreaks': {'automatic': true},
-            // Disable to prevent OTF font loading, which aren't part of our
-            // distribution.
-            'imageFont': null,
-          },
-          'messageStyle': 'none'
-        });
-        mathjax.Hub.Configured();
-      })();
-      </script>
-      '''))
-    
-def Polynomial_to_LaTeX(p):
-    """ Small function to print nicely the polynomial p as we write it in maths, in LaTeX code."""
-    coefs = p.coef[::-1]  # List of coefficient, sorted by increasing degrees
-    res = ""  # The resulting string
-    for i, a in enumerate(coefs):
-        if int(a) == a:  # Remove the trailing .0
-            a = int(a)
-        if i == 0:  # First coefficient, no need for X
-            if a > 0:
-                res += "{a} + ".format(a=a)
-            elif a < 0:  # Negative a is printed like (a)
-                res += "({a}) + ".format(a=a)
-            # a = 0 is not displayed 
-        elif i == 1:  # Second coefficient, only X and not X**i
-            if a == 1:  # a = 1 does not need to be displayed
-                res += "x + "
-            elif a > 0:
-                res += "{a} \;x + ".format(a=a)
-            elif a < 0:
-                res += "({a}) \;x + ".format(a=a)
-        else:
-            if a == 1:
-                # A special care needs to be addressed to put the exponent in {..} in LaTeX
-                res += "x^{i} + ".format(i="{%d}" % i)
-            elif a > 0:
-                res += "{a} \;x^{i} + ".format(a=a, i="{%d}" % i)
-            elif a < 0:
-                res += "({a}) \;x^{i} + ".format(a=a, i="{%d}" % i)
-    return "$" + res[:-3] + "$" if res else ""    
-
- -
-
-
- -
-
- -
- -
-
-
- -
-
-
-
- -
- -
-
-

NumPy Polynomials

-
-
-
-
- -
- -
-
-

In Numpy there is an implementation of Polynomials. The object is initialized giving the polynomial coefficients:

-

More information about this

- - -
-
-
-
- -
- -
-
- -
-
-
p = np.poly1d([1, 2, -3])
-print(p)
-
- -
-
-
- -
-
- -
-
- -
-
   2
-1 x + 2 x - 3
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
print('\thola\nmundo\\')
-
- -
-
-
- -
-
- -
-
- -
-
	hola
-mundo\
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
Polynomial_to_LaTeX(p)
-
- -
-
-
- -
-
- -
-
- - - -
-
'$(-3) + 2 \\;x + x^{2}$'
-
- -
-
-
-
- -
-
- -
- -
-
-

Copy an Paster in a MarkDown cell: $(-3) + 2 \;x + x^{2}$

- -
-
-
-
- -
- -
-
- -
-
-
Latex(Polynomial_to_LaTeX(p))
-
- -
-
-
- -
-
- -
-
- - - -
-$(-3) + 2 \;x + x^{2}$ -
- -
-
-
-
- -
-
- -
- -
-
-

The numpy polynomial is automatically a function of its variable $x$

- -
-
-
-
- -
- -
-
- -
-
-
p(1.3)
-
- -
-
-
- -
-
- -
-
- - - -
-
1.29
-
- -
-
-
-
- -
-
- -
- -
-
-

By default, the assigned the attribute variable is x:

- -
-
-
-
- -
- -
-
- -
-
-
p.variable
-
- -
-
-
- -
-
- -
-
- - - -
-
'x'
-
- -
-
-
-
- -
-
- -
- -
-
-

which can be assigned at initialization

- -
-
-
-
- -
- -
-
- -
-
-
q = np.poly1d([1, 2, -3],variable='t')
-print(q)
-
- -
-
-
- -
-
- -
-
- -
-
   2
-1 t + 2 t - 3
-
-
-
-
-
-
- -
-
- -
- -
-
-

Change of variable

- -
-
-
-
- -
- -
-
- -
-
-
p = np.poly1d([1, 2, -3])
-print(p)
-
- -
-
-
- -
-
- -
-
- -
-
   2
-1 x + 2 x - 3
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
p.coef
-
- -
-
-
- -
-
- -
-
- - - -
-
array([ 1,  2, -3])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
pp=np.poly1d(p.coef,variable='t')
-print(pp)
-
- -
-
-
- -
-
- -
-
- -
-
   2
-1 t + 2 t - 3
-
-
-
-
-
-
- -
-
- -
- -
-
-

Polynomial can be added but not multiplied, simplified or expanded

- -
-
-
-
- -
- -
-
- -
-
-
p1=np.poly1d([1,1])
-print('p1(x)={}'.format(p1))
-print('*'*20)
-p2=np.poly1d([-1,1])
-print('p2(x)={}'.format(p2))
-print('*'*20)
-print('p1(x)+p2(x)={}'.format(p1+p2))
-
- -
-
-
- -
-
- -
-
- -
-
p1(x)= 
-1 x + 1
-********************
-p2(x)= 
--1 x + 1
-********************
-p1(x)+p2(x)= 
-2
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
p1+p2
-
- -
-
-
- -
-
- -
-
- - - -
-
poly1d([2])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
print(p1+p2)
-
- -
-
-
- -
-
- -
-
- -
-
 
-2
-
-
-
-
-
-
- -
-
- -
- -
-
-

The object have in particular methods for
-Integration:

- -
-
-
-
- -
- -
-
- -
-
-
print(p)
-
- -
-
-
- -
-
- -
-
- -
-
   2
-1 x + 2 x - 3
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
p = np.poly1d([1, 2, -3])
-print( p.integ() )
-
- -
-
-
- -
-
- -
-
- -
-
        3     2
-0.3333 x + 1 x - 3 x
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
p.integ().coef
-
- -
-
-
- -
-
- -
-
- - - -
-
array([ 0.33333333,  1.        , -3.        ,  0.        ])
-
- -
-
-
-
- -
-
- -
- -
-
-

Derivatives

- -
-
-
-
- -
- -
-
- -
-
-
print( p.deriv() )
-
- -
-
-
- -
-
- -
-
- -
-
 
-2 x + 2
-
-
-
-
-
-
- -
-
- -
- -
-
-

roots:

- -
-
-
-
- -
- -
-
- -
-
-
setup_typeset() #active colab pretty print
-print(p.roots)
-
- -
-
-
- -
-
- -
-
- - -
- - - - -
- -
-
-
-
- -
-
[-3.  1.]
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
Latex( '$p({})$={}'.format(round(p.roots[0],1),
-                                      p((p.roots[0] )  ) ) )
-
- -
-
-
- -
-
- -
-
- - - -
-$p(-3.0)$=1.7763568394002505e-15 -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
Latex( f'$p({round(p.roots[0],0)})$={p(p.roots[0])}' )
-                                    
-
- -
-
-
- -
-
- -
-
- - - -
-$p(-3.0)$=1.7763568394002505e-15 -
- -
-
-
-
- -
-
- -
- -
-
-

It is possible to define polynomial by given the list of roots and

- -
-
-
-
- -
- -
-
- -
-
-
p=np.poly1d([-246.2,-40,40,246.2],r=True)
-print(p)
-
- -
-
-
- -
-
- -
-
- -
-
   4             2
-1 x - 6.221e+04 x + 9.698e+07
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
p(-40)
-
- -
-
-
- -
-
- -
-
- - - -
-
1.4901161193847656e-08
-
- -
-
-
-
- -
-
- -
- -
-
-

For further details check the official help:

- -
-
-
-
- -
- -
-
- -
-
-
np.poly1d?
-
- -
-
-
- -
-
- -
- -
-
-

Activity: Movement with uniform acceleration

-
    -
  1. Define a polynomial for the movement with uniform acceleration: -\begin{align} -x(t)=x_0+v_0 (t-t_0)+\tfrac{1}{2} a (t-t_0)^2 \,, -\end{align}
  2. -
  3. Use the previous formula expressed as polynomial of degree 2, to solve the following problem with np.poly1d:
      -
    • A car departs from rest with a constant acceleration of $6~\text{m}\cdot\text{s}^{-2}$ and travels through a flat and straight road. 10 seconds later a second pass for the same starting point and in the same direction with an initial speed of $10~\text{m}\cdot\text{s}^{-1}$ and a constant acelleration of $10~\text{m}\cdot\text{s}^{-2}$. Find the time and distance at which the two cars meet.
    • -
    -
  4. -
-

Hint. -\begin{align} -x(t)=x_0-v_0t_0+\frac{1}{2}at_0^2 +(v_0-at_0)t+\tfrac{1}{2} a t^2 -\end{align}

- -
-
-
-
- -
- -
-
- -
-
-
x0=0
-t0=0
-v0=0
-a=6 #m/s^2
-x_1=np.poly1d([0.5*a,v0-a*t0,x0-v0*t0+0.5*a*t0**2],variable='t')
-x0=0
-t0=10 #s
-v0=10 #m/s
-a=10 #m/s^2
-x_2=np.poly1d([0.5*a,v0-a*t0,x0-v0*t0+0.5*a*t0**2],variable='t')
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
print(x_1)
-
- -
-
-
- -
-
- -
-
- -
-
   2
-3 t
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
print(x_2)
-
- -
-
-
- -
-
- -
-
- -
-
   2
-5 t - 90 t + 400
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
-
- -
- -
-
-

Sea el tiempo de encuentro definido $t_e$ -$$x_1(t_e)=x_2(t_e)\,,$$ -que se interpreta como -$$x_1(t_e)-x_2(t_e)=0\,,$$ -Puedo definir un nuevo polinomio -$$ -x(t)=x_1(t)-x_2(t) -$$ -Entonces $t_e$, es la raíz del polinomio $x(t)$

- -
-
-
-
- -
- -
-
- -
-
-
x=x_1-x_2
-print(x)
-
- -
-
-
- -
-
- -
-
- -
-
    2
--2 x + 90 x - 400
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
x.roots
-
- -
-
-
- -
-
- -
-
- - - -
-
array([40.,  5.])
-
- -
-
-
-
- -
-
- -
- -
-
-

La raíz 5 no es física porque el tiempo incial para el segundo carro es 10

- -
-
-
-
- -
- -
-
- -
-
-
x_1[40]
-
- -
-
-
- -
-
- -
-
- - - -
-
0
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
x_2[40]
-
- -
-
-
- -
-
- -
-
- - - -
-
0
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
setup_typeset() #active colab pretty print
-def x(x0,t0,v0,a):
-    return np.poly1d( [0.5*a,v0-a*t0,x0-v0*t0+0.5*a*t0**2],
-                     variable='t'  )
-x1=x(0,0,0,6)
-x2=x(0,10,10,10)
-display(Latex('$x_1(t)=$'))
-print(x1) 
-display(Latex('$x_2(t)=$'))
-print(x2)
-t=np.linspace(0,45,100)
-plt.plot(t,x2(t)-x1(t))
-plt.xlabel('$t$ [s]')
-plt.ylabel('$x_2(t)-x_1(t)$ [m]')
-plt.grid()
-#plt.plot(t,(x2-x1)(t))
-#plt.grid()
-#Physica solution is the one after 10s
-Latex(r'meeting time $t_{\rm end}=$ %g s; meeting point $x_{\rm end}=$ %g m' 
-          %(  (x2-x1).r[0]  ,  x2(  (x2-x1).r[0]  )   )) 
-#plt.plot(t,x2(t),'ro')
-#plt.plot(t,x2(t),'k-')
-#plt.xlim(10,15)
-#plt.ylim(0,200)          
-
- -
-
-
- -
-
- -
-
- - -
- - - - -
- -
-
-
-
- - - -
-$x_1(t)=$ -
- -
-
-
-
- -
-
   2
-3 t
-
-
-
-
-
-
- - - -
-$x_2(t)=$ -
- -
-
-
-
- -
-
   2
-5 t - 90 t + 400
-
-
-
-
-
-
- - - -
-meeting time $t_{\rm end}=$ 40 s; meeting point $x_{\rm end}=$ 4800 m -
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
v=x_2.deriv()
-print(v)
-
- -
-
-
- -
-
- -
-
- -
-
 
-10 x - 90
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
print(v.deriv())
-
- -
-
-
- -
-
- -
-
- -
-
 
-10
-
-
-
-
-
-
- -
-
- -
- -
-
-

Linear Interpolation

-
-
-
-
- -
- -
-
-

When we have a set of discrete points of the form $(x_i, y_i)$ for $1\leq i \leq N$, the most natural way to obtain (approximate) any intermediate value is assuming points connected by lines. Let's assume a set of points $(x_i, y_i)$ such that $y_i = f(x_i)$ for an unknown function $f(x)$, if we want to approximate the value $f(x)$ for $x_i\leq x \leq x_{i+1}$, we construct an equation of a line passing through $(x_i,y_i)$ and $(x_{i+1},y_{i+1})$.

-

The linear equation is

-$$y=mx+b$$

where

-$$m=\frac{y_{i+1}-y_i}{x_{i+1}-x_i} $$

and $b$ is obtained by evaluating with either $(x_i,y_i)$ or $(x_{i+1},y_{i+1})$

-$$y=\frac{y_{i+1}-y_i}{x_{i+1}-x_i}x+b$$$$b=y_i-\frac{y_{i+1}-y_i}{x_{i+1}-x_i}x_i$$\begin{align} -%$$ -f(x)\approx y = &\frac{y_{i+1}-y_i}{x_{i+1}-x_i}(x-x_i) + y_i \\ -=&\frac{y_{i+1}-y_i}{x_{i+1}-x_i}x+\left[y_i-\frac{y_{i+1}-y_i}{x_{i+1}-x_i}x_i\right] \\ -%$$ -\end{align}

and this can be applied for any $x$ such that $x_0\leq x \leq x_N$ and where it has been assumed an ordered set $\left\{x_i\right\}_i$.

- -
-
-
-
- -
- -
-
-

Steps LI

-
-
-
-
- -
- -
-
-

Once defined the mathematical basis behind linear interpolation, we proceed to establish the algorithmic steps for an implementation.

-
    -
  1. Establish the dataset you want to interpolate, i.e. you must provide a set of the form $(x_i,y_i)$.
  2. -
  3. Give the value $x$ where you want to approximate the value $f(x)$.
  4. -
  5. Find the interval $[x_i, x_{i+1}]$ in which $x$ is embedded.
  6. -
  7. Use the above expression in order to find $y=f(x)$.
  8. -
- -
-
-
-
- -
- -
-
-

To make the linear interpolation we will use

- -
-
-
-
- -
- -
-
- -
-
-
import scipy as sp
-sp.interpolate.interp1d?
-
- -
-
-
- -
-
- -
- -
-
-

The option kind specifies the kind of interpolation:

-
    -
  • 'linear', 'nearest', 'zero', 'slinear', 'quadratic', 'cubic', - where 'zero', 'slinear', 'quadratic' and 'cubic' refer to a spline - interpolation of zeroth, first, second or third order)
  • -
  • or as an - integer specifying the order of the spline interpolator to use.
  • -
-

Default is 'linear' correponding to integer 1.

- -
-
-
-
- -
- -
-
-

Example 1

-
-
-
-
- -
- -
-
-

Sample the function $f(x) = \sin(x)$ between $0$ and $10$ using $N=10$ points (9 intervals). Plot both, the interpolation and the original function.

- -
-
-
-
- -
- -
-
- -
-
-
import scipy as sp
-from scipy import interpolate 
-
- -
-
-
- -
-
- -
- -
-
-

sp reemplaza completamente a numpy con np

- -
-
-
-
- -
- -
-
-

Interpolation with 9 equal intervals

- -
-
-
-
- -
- -
-
- -
-
-
n_points = 10
-x=np.linspace(0, 2*np.pi, n_points)
-f=interpolate.interp1d( x,np.sin(x),kind='linear' )
-
- -
-
-
- -
-
- -
- -
-
-

Plotting the results adding the real function with enough points

- -
-
-
-
- -
- -
-
- -
-
-
Ninter = 100
-X=np.linspace(0, 2*np.pi, Ninter)
-plt.figure( figsize=(12,6) )
-plt.plot(x,f(x),'ro',label='Data')
-plt.plot(X,f(X),'k-',lw=3,label='linear interpolation')
-plt.plot(X,np.sin(X),'c-',label='real function')
-
-#Formatting
-plt.plot(2.35,f(2.35),'y*',markersize=10,label='sample point')
-plt.title( "Linear interpolation of $\sin(x)$" )
-plt.legend()
-plt.xlabel( "$x$",size=15 )
-plt.ylabel( "$y$",size=15 )
-plt.grid()
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Other kind values: 0,1,2

- -
-
-
-
- -
- -
-
- -
-
-
%pylab inline
-
- -
-
-
- -
-
- -
-
- -
-
Populating the interactive namespace from numpy and matplotlib
-
-
-
-
-
-
- -
-
/usr/local/lib/python3.5/dist-packages/IPython/core/magics/pylab.py:160: UserWarning: pylab import has clobbered these variables: ['f']
-`%matplotlib` prevents importing * from pylab and numpy
-  "\n`%matplotlib` prevents importing * from pylab and numpy"
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
n_points = 10
-x=np.linspace(0, 2*np.pi, n_points)
-Ninter = 100
-X=np.linspace(0, 2*np.pi, Ninter)
-plt.figure( figsize=(12,6) )
-plt.plot(x,np.sin(x),'ro',label='Data')
-plt.plot(X,np.sin(X),'c-',label='real function')
-
-plt.plot(X,interpolate.interp1d( x,np.sin(x),kind=0)(X),
-         'g--',lw=1,label='interpolation with horizontal lines')
-plt.plot(X,interpolate.interp1d( x,np.sin(x),kind=1)(X),
-         'k-',lw=1,label='linear interpolation')
-plt.plot(X,interpolate.interp1d( x,np.sin(x),kind=2)(X),
-         'r:',lw=1,label='quadratic interpolation')
-#plt.plot(X,interpolate.interp1d( x,np.sin(x),kind=3)(X),
-#         'k:',lw=1,label='quadratic interpolation')
-
-#Formatting
-plt.plot(2.35,f(2.35),'y*',markersize=10,label='sample point')
-plt.title( "Linear interpolation of $\sin(x)$" )
-plt.legend()
-plt.xlabel( "$x$",size=15 )
-plt.ylabel( "$y$",size=15 )
-
-#Formatting
-plt.title( "Linear interpolation of $\sin(x)$" )
-plt.legend()
-plt.xlabel( "$x$",size=15 )
-plt.ylabel( "$y$",size=15 )
-plt.grid()
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

We can see that the data poinst are just joined by straight lines:

- -
-
-
-
- -
- -
-
- -
-
-
f(2.35),np.sin(2.35)
-
- -
-
-
- -
-
- -
-
- - - -
-
(array(0.67198441), 0.7114733527908443)
-
- -
-
-
-
- -
-
- -
- -
-
-

However, the object f behaves like a function. For example. We can evaluate both the real and the interpolated function in $x_0=3$

- -
-
-
-
- -
- -
-
- -
-
-
np.sin(3)
-
- -
-
-
- -
-
- -
-
- - - -
-
0.1411200080598672
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
f(3)
-
- -
-
-
- -
-
- -
-
- - - -
-
array(0.13335233)
-
- -
-
-
-
- -
-
- -
- -
-
-

Activity

-

Use the previous code and explore the behaviour of the Linear Interpolation algorithm when varying the number of data used.

- -
-
-
-
- -
- -
-
- -
-
-
-
- -
- -
-
-
- -
-
-
-
- -
- -
-
-

Example:

Generate three points that do not lie upon a stright line, and try to make a manual interpolation with a polynomial of degree two.

- -
-
-
-
- -
- -
-
- -
-
-
import pandas as pd
-df=pd.DataFrame({ 'X':[-2.4,3,21.3],
-                  'Y':[-10.,8.,3.]
-                 }  
-                )
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
df
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
XY
0-2.4-10.0
13.08.0
221.33.0
-
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
plt.plot(df.X,df.Y,'ro')
-plt.grid()
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
import scipy as sp
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
f=sp.interpolate.interp1d(df.X,df.Y)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
f(0)
-
- -
-
-
- -
-
- -
-
- - - -
-
array(-2.)
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
plt.plot(df.X,df.Y,'ro')
-plt.plot(df.X,f(df.X),'b-')
-plt.plot(5,f(5),'y*')
-plt.grid()
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Polynomial object in numpy

In numpy it is possible to define polynomials friom either its coefficients o its roots with np.poly1d

- -
-
-
-
- -
- -
-
-

Define a two degree polynomial from its roots:

- -
-
-
-
- -
- -
-
- -
-
-
import numpy as np
-
- -
-
-
- -
-
- -
- -
-
-

We try to make a fit by using an inverted parabola passing trough the tree points and using the roots as a guess. -In fact, we can try with a polynomial of degree two with roots at 1 and 22.

-

With $k$ we can flip the curve and reduce the maximum without change the roots

- -
-
-
-
- -
- -
-
- -
-
-
k=-0.1
-P=k*np.poly1d([0,23],r=True)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
print(P)
-
- -
-
-
- -
-
- -
-
- -
-
      2
--0.1 x + 2.3 x - 0
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
P.roots
-
- -
-
-
- -
-
- -
-
- - - -
-
array([23.,  0.])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
plt.plot(df.X,df.Y,'ro')
-x=np.linspace(-8,30)
-plt.plot(x,P( x),'b-')
-plt.grid()
-plt.xlim(-8,30)
-plt.ylim(-15,20)
-
- -
-
-
- -
-
- -
-
- - - -
-
(-15.0, 20.0)
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Activity: Scipy interpolation.

-

Define an interplation function which passes throgh the three points by using interp1D of Scipy with several linear and quadratic curves between the points.

- -
-
-
-
- -
- -
-
- -
-
-
-
- -
- -
-
-

Interpolation with numpy

numpy already include an interpolation function with polynomials called np.polyfit

- -
-
-
-
- -
- -
-
-
np.polyfit(x, y, deg, rcond=None, full=False, w=None, cov=False)
-
-

Least squares polynomial fit.

-

Fit a polynomial p(x) = p[0] * x**deg + ... + p[deg] of degree deg -to points (x, y). Returns a vector of coefficients p that minimises -the squared error.

- -
-
-
-
- -
- -
-
-

To fit a set of x and y we need to specify the degree of the polynial to make the fit with the madatory argument: deg

- -
-
-
-
- -
- -
-
-

Example: fit the points of the previous DataFrame with a polynomial of degree 3

- -
-
-
-
- -
- -
-
- -
-
-
coeffs=np.polyfit(df.X,df.Y,deg=2)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
coeffs
-
- -
-
-
- -
-
- -
-
- - - -
-
array([-0.15217542,  3.42463858, -0.904337  ])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
np.poly1d(coeffs).roots
-
- -
-
-
- -
-
- -
-
- - - -
-
array([22.2373041 ,  0.26724135])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
print(np.poly1d(coeffs))
-
- -
-
-
- -
-
- -
-
- -
-
         2
--0.1522 x + 3.425 x - 0.9043
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
coeffs=np.polyfit(df.X,df.Y,deg=2)
-P=np.poly1d(coeffs)
-plt.plot(df.X,df.Y,'ro')
-x=np.linspace(-8,30,100)
-plt.plot(x,P( x),'b-')
-plt.grid()
-plt.ylim(-20,20)
-
- -
-
-
- -
-
- -
-
- - - -
-
(-20.0, 20.0)
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Example: Least action

see Least action Notebook: [local] [GitHub]

- -
-
-
-
- -
- -
-
- -
-
-
#np.poly1d?
-
- -
-
-
- -
-
- -
- -
-
-

Lagrange Polynomial

-
-
-
-
- -
- -
-
-

Algebraic polynomials are very special functions as they have properties like differentiability (unlike linear interpolation) and continuity that make them useful for approximations like interpolation. A Polynomial is defined as a function given by the general expression:

-$$P_n(x) = a_nx^n + a_{n-1}x^{n-1} + \cdots + a_1 x + a_0$$

where $n$ is the polynomial degree.

-

Another important property of polynomials is given by the Weierstrass Approximation Theorem, which states given a continuous function $f$ defined on a interval $[a,b]$, for all $\epsilon >0$, there exits a polynomial $P(x)$ such that

-$$|f(x) - P(x)|<\epsilon\ \ \ \ \ \mbox{for all }\ x\ \mbox{ in }\ [a,b].$$

This theorem guarantees the existence of such a polynomial, however it is necessary to propose a scheme to build it.

- -
-
-
-
- -
- -
-
- -
-
-
import pandas as pd
-df=pd.DataFrame({ 'X':[3,21.3],
-                  'Y':[8.,3.]
-                 }  
-                )
-df
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - -
XY
03.08.0
121.33.0
-
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
plt.plot(df.X,df.Y,'ro')
-plt.grid()
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Polinomio de interp. de grado 0

- -
-
-
-
- -
- -
-
- -
-
-
coeffs=np.polyfit(df.X,df.Y,deg=0)
-
-P=np.poly1d(coeffs)
-plt.plot(df.X,df.Y,'ro')
-x=np.linspace(-8,30)
-plt.plot(x,P( x),'b-')
-plt.grid()
-plt.ylim(0,12)
-
-print(np.poly1d(coeffs))
-
- -
-
-
- -
-
- -
-
- -
-
 
-5.5
-
-
-
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Polinomio de interp. de grado 1

- -
-
-
-
- -
- -
-
- -
-
-
coeffs=np.polyfit(df.X,df.Y,deg=1)
-
-P=np.poly1d(coeffs)
-plt.plot(df.X,df.Y,'ro')
-x=np.linspace(-8,30)
-plt.plot(x,P( x),'b-')
-plt.grid()
-plt.ylim(0,12)
-
-print(np.poly1d(coeffs))
-
- -
-
-
- -
-
- -
-
- -
-
 
--0.2732 x + 8.82
-
-
-
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Polinomio de interp. de grado 2

- -
-
-
-
- -
- -
-
- -
-
-
coeffs=np.polyfit(df.X,df.Y,deg=2)
-
-P=np.poly1d(coeffs)
-plt.plot(df.X,df.Y,'ro')
-x=np.linspace(-8,30)
-plt.plot(x,P( x),'b-')
-plt.grid()
-plt.ylim(0,12)
-
-print(np.poly1d(coeffs))
-
- -
-
-
- -
-
- -
-
- -
-
           2
--0.008617 x - 0.06383 x + 8.269
-
-
-
-
-
-
- -
-
/usr/local/lib/python3.7/dist-packages/IPython/core/interactiveshell.py:3418: RankWarning: Polyfit may be poorly conditioned
-  exec(code_obj, self.user_global_ns, self.user_ns)
-
-
-
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
df=df.append({'X':10,'Y':6.5},ignore_index=True).sort_values('X')
-df.to_csv('../data/interpolation.csv',index=False)
-df
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
XY
03.08.0
210.06.5
121.33.0
-
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
coeffs=np.polyfit(df.X,df.Y,deg=2)
-
-P=np.poly1d(coeffs)
-plt.plot(df.X,df.Y,'ro')
-x=np.linspace(-8,30)
-plt.plot(x,P( x),'b-')
-plt.grid()
-plt.ylim(0,12)
-
-print(np.poly1d(coeffs))
-
- -
-
-
- -
-
- -
-
- -
-
           2
--0.005216 x - 0.1465 x + 8.486
-
-
-
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
print(np.poly1d(coeffs))
-
- -
-
-
- -
-
- -
-
- -
-
           2
--0.005216 x - 0.1465 x + 8.486
-
-
-
-
-
-
- -
-
- -
- -
-
-

Derivation

-
-
-
-
- -
- -
-
-

Let's suppose a well-behaved yet unknown function $f$ and two points $(x_0,y_0)$ and $(x_1,y_1)$ for which $f(x_0) = y_0$ and $f(x_1) = y_1$. With this information we can build a first-degree polynomial that passes through both points by using the last equation in sec. Linear Interpolation, we have

-$$P_1(x) = \left[ \frac{y_{1}-y_0}{x_{1}-x_0} \right]x + \left[ y_0 - \frac{y_{1}-y_0}{x_{1}-x_0}x_0 \right]$$

We can readily rewrite this expression like: -\begin{align} -P_1(x) =& \frac{y_{1}}{x_{1}-x_0} x- \frac{y_0}{x_{1}-x_0} x + y_0 -\frac{y_{1}}{x_{1}-x_0}x_0 + \frac{y_0}{x_{1}-x_0}x_0 \nonumber\\ -=& \left[1 - \frac{x}{x_{1}-x_0} + \frac{x_0}{x_{1}-x_0}\right]y_0+ -\left[\frac{x}{x_{1}-x_0} -\frac{x_0}{x_{1}-x_0}\right]y_1 \nonumber\\ - =& \left[\frac{x_1-x_0}{x_{1}-x_0} - \frac{x}{x_{1}-x_0} + \frac{x_0}{x_{1}-x_0}\right]y_0+ -\left[\frac{x}{x_{1}-x_0} -\frac{x_0}{x_{1}-x_0}\right]y_1 \nonumber\\ -=& \left[\frac{x_1-x}{x_{1}-x_0}\right]y_0+ -\left[\frac{x-x_0}{x_{1}-x_0}\right]y_1 \,. -\end{align} -In this way -$$P_1(x) = L_0(x)f(x_0) + L_1(x)f(x_1)$$

-

where we define the functions $L_0(x)$ and $L_1(x)$ as:

-$$L_0(x) = \frac{x-x_1}{x_0-x_1} \mbox{ and } L_1(x) = \frac{x-x_0}{x_1-x_0}$$

Note that

-$$L_0(x_0) = 1,\ \ \ L_0(x_1) = 0,\ \ \ L_1(x_0) = 0,\ \ \ L_1(x_1) = 1$$

implying:

-$$P_1(x_0) = f(x_0) = y_0$$$$P_1(x_1) = f(x_1) = y_1$$

Although all this procedure may seem unnecessary for a polynomial of degree 1, a generalization to polynomials of larger degrees is now possible.

- -
-
-
-
- -
- -
-
-

General case

Let's assume again a well-behaved and unknown function $f$ sampled by using a set of $n+1$ data $(x_m,y_m)$ ($0\leq m \leq n$). -We call the set of $[x_0,x_1,\ldots,x_n]$ as the node points of the interpolation polynomial in the Lagrange form, $P_n(x)$, where: -$$f(x)\approx P_n(x)\,,$$

-$$P_n(x) = \sum_{i=0}^n f(x_i)L_{n,i}(x) = \sum_{i=0}^n y_iL_{n,i}(x)$$

Such that -$$f(x_i)= P_n(x_i)\,,$$

-

We need to find the Lagrange polynomials, $L_{n,i}(x)$, such that -$$L_{n,i}(x_i) = 1\,,\qquad\text{and}\,,\qquad L_{n,i}(x_j) = 0\quad\text{for $i\neq j$}$$ -A function that satisfies this criterion is

-$$L_{n,i}(x) = \prod_{\begin{smallmatrix}m=0\\ m\neq i\end{smallmatrix}}^n \frac{x-x_m}{x_i-x_m} =\frac{(x-x_0)}{(x_i-x_0)}\frac{(x-x_1)}{(x_i-x_1)}\cdots \frac{(x-x_{i-1})}{(x_i-x_{i-1})}\underbrace{\frac{}{}}_{m\ne i} -\frac{(x-x_{i+1})}{(x_i-x_{i+1})} \cdots \frac{(x-x_{n-1})}{(x_i-x_{n-1})}\frac{(x-x_n)}{(x_i-x_n)} $$

Please note that in the expansion the term $(x-x_i)$ does not appears in both the numerator and the denominator as stablished in the productory condition $m\neq i$.

-

Moreower -$$L_{n,i}(x_i) = \prod_{\begin{smallmatrix}m=0\\ m\neq i\end{smallmatrix}}^n \frac{x_i-x_m}{x_i-x_m} =1$$ -and, for $j\ne i$ -$$L_{n,i}(x_j) = \prod_{\begin{smallmatrix}m=0\\ m\neq i\end{smallmatrix}}^n \frac{x_j-x_m}{x_i-x_m} =\frac{(x_j-x_0)}{(x_i-x_0)}\cdots \frac{(\boldsymbol{x_j}-\boldsymbol{x_j})}{(x_i-x_j)}\cdots\frac{(x_j-x_n)}{(x_i-x_n)}=0.$$

-

Then, the polynomial of $n$th-degree $P_n(x)$ will satisfy the definitory property for a interpolating polynomial, i.e. $P_n(x_i) = y_i$ for any $i$ and it is called the interpolation Polynomial in the Lagrange form.

-

Check this implementation in sympy [View in Colaboratory] where both the interpolating polynomial and the Lagrange polynomials are defined.

- -
-
-
-
- -
- -
-
-

Further details at: -Wikipedia

- -
-
-
-
- -
- -
-
-

Example:

Obtain the Lagrange Polynomials for a Interpolation polynomial of degree 1.

- -
-
-
-
- -
- -
-
-

$i=0$, $n=1$ -$$ L_{1,0}=\prod_{\begin{smallmatrix}m=0\\ m\neq 0\end{smallmatrix}}^1 \frac{x-x_m}{x_i-x_m}=\prod_{\begin{smallmatrix}m=1\end{smallmatrix}}^1 \frac{x-x_m}{x_0-x_m}=\frac{x-x_1}{x_0-x_1}$$ -$i=1$, $n=1$ -$$ L_{1,1}=\prod_{\begin{smallmatrix}m=0\\ m\neq 1\end{smallmatrix}}^1 \frac{x-x_m}{x_i-x_m}=\prod_{\begin{smallmatrix}m=0\end{smallmatrix}}^0 \frac{x-x_m}{x_1-x_m}=\frac{x-x_0}{x_1-x_0}$$

- -
-
-
-
- -
- -
-
-

Until now we can only guarantee that $P_n(x_i)=f(x_i)$. To calculate the function from any $x$ in the interpolation interval we have the following Theorem (See here)

-

Theorem

Suppose $X_0,\ldots,x_n$ are distinct numbers in the interval $[a,b]$ and $f\in[a,b]$.Then for each $x$ in $[a,b]$, a number $\xi(x)$ between $x_0,\ldots,x_n$, and hence in $[a,b]$, exists with -$$ -f(x)=P_n(x)+E_n(x)\,,\qquad \text{such that } E_n(x_i)=0\,, -$$ -where the formula for the error bound is given by -$$ -E_n(x) = {f^{n+1}(\xi(x)) \over (n+1)!} \cdot \prod_{i=0}^{n}\left(x-x_{i}\right)\,, -$$ -$f^{(n+1)}$ is the $n+1$ derivative of $f$

-

For a demostration see [1d] → https://www.math.ust.hk/~mamu/courses/231/Slides/CH03_1B.pdf

-

The specific calculation of the bounded error is to find the $\xi$ and $x$ such that -$$ -\left|f(x)-P(x)\right| \leq \max_{\xi\in[a,b]}\left|\frac{f^{(n+1)}(\xi)}{(n+1) !}\right| \cdot \max_{x\in[a,b]}\left|\prod_{i=0}^{n}\left(x-x_{i}\right)\right| -$$

- -
-
-
-
- -
- -
-
-

Exercise-interpolation

Obtain the Lagrange Polynomials for a Interpolation polynomial of degree 2.

- -
-
-
-
- -
- -
-
-

Implementation in Scipy

-
-
-
-
- -
- -
-
- -
-
-
from scipy import interpolate
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
#interpolate.lagrange?
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
df
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
XY
03.08.0
210.06.5
121.33.0
-
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
P=interpolate.lagrange(df.X,df.Y)
-print(P)
-
- -
-
-
- -
-
- -
-
- -
-
           2
--0.005216 x - 0.1465 x + 8.486
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
plt.plot(df.X,df.Y,'ro')
-x=np.linspace(-8,30)
-plt.plot(x,P( x),'b-')
-plt.grid()
-plt.ylim(0,12)
-
- -
-
-
- -
-
- -
-
- - - -
-
(0.0, 12.0)
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Example of error calculation

See details here

-

Consider $f(x) = \operatorname{e}^{2x} - x$ interpolation in the interval $[1,1.6]$

-
    -
  1. Construct the Lagrange Polynomial for the points $x_0=1$, $x_1=1.25$, $x_2=1.6$.
  2. -
  3. Find the approximate value at $f(1.5)$ and the error bound for the approximation
  4. -
- -
-
-
-
- -
- -
-
-
    -
  1. We start by defining the function
  2. -
-

Be sure that the function input will be an array

- -
-
-
-
- -
- -
-
- -
-
-
#Wrong result for a list
-x=[1,1.25,1.6]
-np.exp(2*x)
-
- -
-
-
- -
-
- -
-
- - - -
-
array([2.71828183, 3.49034296, 4.95303242, 2.71828183, 3.49034296,
-       4.95303242])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
x+x
-
- -
-
-
- -
-
- -
-
- - - -
-
[1, 1.25, 1.6, 1, 1.25, 1.6]
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
2*x
-
- -
-
-
- -
-
- -
-
- - - -
-
[1, 1.25, 1.6, 1, 1.25, 1.6]
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
np.exp(2*np.array(x))
-
- -
-
-
- -
-
- -
-
- - - -
-
array([ 7.3890561 , 12.18249396, 24.5325302 ])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#List operations are not well defined in general
-[1,2,4]-[1,5,6]
-
- -
-
-
- -
-
- -
-
- -
-
----------------------------------------------------------------------------
-TypeError                                 Traceback (most recent call last)
-<ipython-input-70-641c9f212de0> in <module>()
-      1 #List operations are not well defined in general
-----> 2 [1,2,4]-[1,5,6]
-
-TypeError: unsupported operand type(s) for -: 'list' and 'list'
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
def f(x):
-    '''
-    WARNING: all the parts of the function must be 
-    numpy arrays in order to get the element by element sum.
-    '''
-    x=np.asarray(x) # Force x → array
-    return np.exp(2*x)-x
-
- -
-
-
- -
-
- -
- -
-
-

The interpolation polynomial is

- -
-
-
-
- -
- -
-
- -
-
-
x=[1,1.25,1.6]
-P_2=interpolate.lagrange(x,f(x))
-print(P_2)
-
- -
-
-
- -
-
- -
-
- -
-
       2
-26.85 x - 42.25 x + 21.78
-
-
-
-
-
-
- -
-
- -
- -
-
-

Test interpolation with one of the three points

- -
-
-
-
- -
- -
-
- -
-
-
P_2(x[1]),f(x[1])
-
- -
-
-
- -
-
- -
-
- - - -
-
(10.932493960703491, 10.932493960703473)
-
- -
-
-
-
- -
-
- -
- -
-
-

For the bounded error we start with the left part -$$ -\max_{\xi\in[1,1.6]}\left|\frac{f'''(\xi)}{(3)!}\right| -$$ -where -$$f'(x)=2\operatorname{e}^{2x}-1$$ -$$f''(x)=4\operatorname{e}^{2x}$$ -$$f'''(x)=8\operatorname{e}^{2x}$$ -The maximum is obtained for the last point $x_2$

- -
-
-
-
- -
- -
-
- -
-
-
fppp=8*np.exp(2*x[2])
-fppp
-
- -
-
-
- -
-
- -
-
- - - -
-
196.26024157687482
-
- -
-
-
-
- -
-
- -
- -
-
-

For the right part -$$ -\max_{x\in[a,b]}\left|\prod_{i=0}^{2}\left(x-x_{i}\right)\right|= -$$ -we need just to build the numpy polynomial with roots at $(x_0,x_1,x_2)$ -$$ -p_e(x)=(x-x_0)(x-x_1)(x-x_2)\,, -$$

- -
-
-
-
- -
- -
-
- -
-
-
p_e=np.poly1d(x,r=True)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
X=np.linspace( x[0],x[-1]  )
-plt.plot(X,p_e(X))
-plt.plot(X,p_e.deriv()(X))
-plt.ylim(-0.02,0.01)
-plt.grid()
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

And find the maximun of the absolute value of the critical points

- -
-
-
-
- -
- -
-
- -
-
-
p_e.deriv().roots
-
- -
-
-
- -
-
- -
-
- - - -
-
array([1.45733844, 1.10932822])
-
- -
-
-
-
- -
-
- -
- -
-
-

The point in the interval $[1,1.6]$ for which $|p_e(x)|$ is maximum corresponds to the root

- -
-
-
-
- -
- -
-
- -
-
-
xmax=p_e.deriv().roots[0]
-xmax
-
- -
-
-
- -
-
- -
-
- - - -
-
1.4573384418151778
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
np.abs(p_e(xmax))
-
- -
-
-
- -
-
- -
-
- - - -
-
0.013527716754363928
-
- -
-
-
-
- -
-
- -
- -
-
-

Or

- -
-
-
-
- -
- -
-
- -
-
-
p_emax=np.abs( p_e(p_e.deriv().roots) ).max()
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
p_emax
-
- -
-
-
- -
-
- -
-
- - - -
-
0.013527716754363928
-
- -
-
-
-
- -
-
- -
- -
-
-

In this way, the maximum error for $p(x)$ is expected for $x_{\text{max}}=1.45733844$

- -
-
-
-
- -
- -
-
-

The bounded error is then -$$ -E_2(x)=\max_{\xi\in[1,1.6]}\left|\frac{f'''(\xi)}{(3)!}\right|\cdot\max_{x\in[a,b]}\left|\prod_{i=0}^{2}\left(x-x_{i}\right)\right| -$$

- -
-
-
-
- -
- -
-
- -
-
-
E_2=fppp/(2*3)*p_emax
-E_2
-
- -
-
-
- -
-
- -
-
- - - -
-
0.4424921596991669
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
X=1.5
-f(X)
-
- -
-
-
- -
-
- -
-
- - - -
-
18.585536923187668
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
P_2(X)
-
- -
-
-
- -
-
- -
-
- - - -
-
18.832612316478652
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
P_2(X)-f(X)
-
- -
-
-
- -
-
- -
-
- - - -
-
0.24707539329098438
-
- -
-
-
-
- -
-
- -
- -
-
-

The real bounded error is

- -
-
-
-
- -
- -
-
- -
-
-
xlin=np.linspace(x[0],x[-1],100)
-np.abs(P_2(xlin)-f(xlin)).max()
-
- -
-
-
- -
-
- -
-
- - - -
-
0.26182823963596036
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
plt.plot(X,P_2(X))
-plt.plot(X,f(X))
-plt.grid()
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
plt.plot(X,np.abs(P_2(X)-f(X) ))
-plt.grid()
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Implementation in sympy

For details see here

- -
-
-
-
- -
- -
-
- -
-
-
%pylab inline
-
- -
-
-
- -
-
- -
-
- -
-
Populating the interactive namespace from numpy and matplotlib
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
df=pd.read_csv('https://github.com/restrepo/ComputationalMethods/raw/master/data/interpolation.csv')
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
import LagrangePolynomial as LP
-LP.lagrangePolynomial(df.X,df.Y)
-
- -
-
-
- -
-
- -
-
- - - -
-$\displaystyle - 0.00521578136549848 x^{2} - 0.146480556534234 x + 8.48638370189219$ -
- -
-
-
-
- -
-
- -
- -
-
-$$P_n(x) = \sum_{i=0}^n L_{n,i}(x) \, y_i$$ -
-
-
-
- -
- -
-
- -
-
-
LP.polyL( df.X,0)*df.Y[0]+LP.polyL( df.X,1)*df.Y[1]+LP.polyL( df.X,2)*df.Y[2]
-
- -
-
-
- -
-
- -
-
- - - -
-$\displaystyle 0.0559573894841558 x^{2} - 1.44173177757974 x + 11.8215788273818$ -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
df
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
XY
03.08.0
210.06.5
121.33.0
-
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
df.X[0]
-
- -
-
-
- -
-
- -
-
- - - -
-
3.0
-
- -
-
-
-
- -
-
- -
- -
-
-

Steps LP

-
-
-
-
- -
- -
-
-

Once defined the formal procedure for constructing a Lagrange Polynomial, we proceed to describe the explicit algorithm:

-
    -
  1. Give the working dataset $(x_i, y_i)$ and stablish how many points you have.
  2. -
  3. Define the functions $L_{n,i}(x)$ in a general way.
  4. -
  5. Add each of those terms as shown in last expression.
  6. -
  7. Evaluate your result wherever you want.
  8. -
- -
-
-
-
- -
- -
-
-

Activity

-

Along with the professor, write an implementation of the previous algorithm during classtime.

- -
-
-
-
- -
- -
-
-

Activity LP

-
-
-
-
- -
- -
-
-
- -

One of the very first evidences of the existence of dark matter was the flat rotation curves of spiral galaxies. If we assume the total budget of mass of a galaxy is entirely made of luminous matter, the orbital circular velocity of stars around the galaxy plane should decay according to a keplerian potential. However this is not the case and the circular velocity barely decreases at larger radius, thus indicating the presence of a new non-visible matter component (dark matter). When it is necessary to determine how massive is the dark matter halo embedding a galaxy, an integration of the circular velocity is required. Nevertheless, due to the finite array of a CCD camera, only a discrete set of velocities can be measured and interpolation techniques are required.

-

In this activity we will take a discrete dataset of the circular velocity as a function of the radius for the galaxy NGC 7331 and perform both, a linear and a Lagrange interpolation. You can download the dataset from this link.

- -
-
-
-
- -
- -
-
-

Video

- -
-
-
-
- -
- -
-
-

-**TRIVIA**
-To which of two curves the real data approach better? -

- -
-
-
-
- -
- -
-
-

import os -os.remove('trivia_results.txt')

- -
-
-
-
- -
- -
-
- -
-
-
f=open('trivia_results.txt','a')
-AB=input(r'''A: to the curve "velocity goes to zero when distance goes to infinity"
-B: to the curve "velocity goes to high constant when distance goes to infinity"
-''')
-f.write( '{}\n'.format(AB) )
-f.close()
-
- -
-
-
- -
-
- -
-
- - -
-
-
-
- -
-
- -
- -
-
- -
-
-
fr=open('trivia_results.txt')
-print( fr.read())
-fr.close()
-
- -
-
-
- -
-
- -
-
- -
-
C
-A
-
-
-
-
-
-
-
- -
-
- -
- -
-
-

os.remove('trivia_results.txt')

- -
-
-
-
- -
- -
-
-

Lets us check!

-
-
-
-
- -
- -
-
- -
-
-
#DATA URL: 
-url='https://raw.githubusercontent.com/restrepo/ComputationalMethods/master/data/NGC7331.csv'
-df=pd.read_csv(url)
-df[0:5]
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
rv
00.0533.42496
10.1071.70398
20.1595.14708
30.20107.32276
40.25117.44285
-
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
plt.plot(df.r,df.v,'r.')
-
- -
-
-
- -
-
- -
-
- - - -
-
[<matplotlib.lines.Line2D at 0x7f90fc1f98d0>]
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Build expected data

- -
-
-
-
- -
- -
-
- -
-
-
dff=df[:60]
-#dff=dff.append(pd.DataFrame( {'r':[5,10],'v':[60,20]} )).reset_index(drop=True) # ,15,20,25,30 ,120,105,100,98
-#dff=dff.append(pd.DataFrame( {'r':[3.5,4,10],'v':[230,200,20]} )).reset_index(drop=True) # ,15,20,25,30 ,120,105,100,98
-dff=dff.append(pd.DataFrame( {'r':[3.5,4,9],'v':[230,200,22]} )).reset_index(drop=True) # ,15,20,25,30 ,120,105,100,98
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
plt.plot(df['r'],df['v'],'r-')
-plt.plot(dff.r, dff.v,'b.')
-
- -
-
-
- -
-
- -
-
- - - -
-
[<matplotlib.lines.Line2D at 0x7f90f8970128>]
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
plt.plot(df['r'],1./df['v'],'r-')
-plt.plot(dff['r'],1./dff['v'],'b.')
-
- -
-
-
- -
-
- -
-
- - - -
-
[<matplotlib.lines.Line2D at 0x7f63a0b58748>]
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
coeff=np.polyfit(dff['r'],1./dff['v'],2)
-P=poly1d(coeff,variable='r')
-print(P)
-
- -
-
-
- -
-
- -
-
- -
-
          2
-0.001084 r - 0.00594 r + 0.01169
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
r=np.logspace( np.log10(0.001),np.log10(30 ),100 )
-plt.plot(dff['r'],1./dff['v'],'b.')
-plt.plot(r,P(r),'k-')
-
- -
-
-
- -
-
- -
-
- - - -
-
[<matplotlib.lines.Line2D at 0x7f63a0b687f0>]
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
plt.plot(df['r'],df['v'],'r-')
-plt.plot(dff['r'],dff['v'],'b.')
-plt.plot(r,1/P(r),'k-')
-
- -
-
-
- -
-
- -
-
- - - -
-
[<matplotlib.lines.Line2D at 0x7f63a0a0cc88>]
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-
- -
-
-
-
- -
- -
-
- -
-
-
np.log(2)/0.105
-
- -
-
-
- -
-
- -
-
- - - -
-
6.601401719618527
-
- -
-
-
-
- -
-
- -
- -
-
-

Logarithmic interpolation

See: https://stackoverflow.com/a/29359275/2268280

- -
-
-
-
- -
- -
-
-

Appendix

Thecnical details of interpolation functions: interpolation_details.ipynb

- -
-
-
-
- -
- -
-
-

some *blue* text.

-

Hola

- -
-
-
-
- - - - -
- \ No newline at end of file diff --git a/_build/features/interpolation_details.html b/_build/features/interpolation_details.html deleted file mode 100644 index d09644d..0000000 --- a/_build/features/interpolation_details.html +++ /dev/null @@ -1,576 +0,0 @@ ---- -redirect_from: - - "/features/interpolation-details" -interact_link: content/features/interpolation_details.ipynb -kernel_name: python3 -kernel_path: content/features -has_widgets: false -title: |- - Hemite interpolation -pagenum: 13 -prev_page: - url: /features/LagrangePoly.html -next_page: - url: /features/Minimization.html -suffix: .ipynb -search: x y f xi frac z n left right d divided polynomials hermite cdots order differences equiv k polynomial lagrange function colab points using ik font com ipynb interpolation expression p dk any color derivative research google computationalmethods master interpolationdetails pn set data obtain zeroth difference example coefficients span taylor however dataset github blob material interpolating next given note previous through sum red both calculate point equal real href restrepo target parentimg src assets badge svg alt open functions such expressions different notation suppose where determined yi interpolant cdotsa align also style defined show specific those only derivatives approximated assume - -comment: "***PROGRAMMATICALLY GENERATED, DO NOT EDIT. SEE ORIGINAL FILES IN /content***" ---- - -
-
Hemite interpolation
-
-
- -
-
-

Open In Colab

- -
-
-
-
- -
- -
-
-

Appendix

Thecnical details of interpolation functions: interpolation_details.ipynb -Open In Colab

- -
-
-
-
- -
- -
-
-

Divided Differences

-
-
-
-
- -
- -
-
-

In spite of the good precision achieved by the Lagrange interpolating polynomials, analytical manipulation of such an expressions is rather complicated. Furthermore, when applying other polynomials-based techniques like Hermite polynomials, the algorithms present very different ways to achieve the final interpolation, making a comparison unclear.

-

Divided differences is a way to standardize the notation for interpolating polynomials. Suppose a polynomial $P_n(x)$ and write it in the next form:

-$$P_n(x) = a_0 + a_1(x-x_0)+ a_2 (x-x_0)(x-x_1)+\cdots + a_n(x-x_0)\cdots (x-x_{n-1})$$ -
-
-
-
- -
- -
-
-

where $a_i$ are a set of constants to be determined from the given data $(x_i, y_i)$.

-
    -
  • Obtain $a_0$
    Note that due to the definition of an interpolant function, previous expression should satisfy:
  • -
-$$P_{n}\left(x_{0}\right)=a_{0}=f\left(x_{0}\right)=y_{0}$$
    -
  • Obtain $a_1$ -$$\frac{P_{n}(x)-a_{0}}{x-x_{0}}=\frac{P_{n}(x)-y_{0}}{x-x_{0}}=a_{1}+a_{2}\left(x-x_{1}\right)+\cdots+a_{n}\left(x-x_{1}\right) \cdots\left(x-x_{n}\right)$$
  • -
-$$\frac{P_{n}\left(x_{1}\right)-y_{0}}{x_1-x_{0}}=a_{1}=\frac{y_{1}-y_{0}}{x_1-x_{0}}$$
    -
  • Obtain $a_2$ $$ -\frac{1}{x-x_{1}}\left(\frac{P_{n}(x)-y_{0}}{x-x_{0}}-\frac{y_{1}-y_{0}}{x_{1}-x_{0}}\right)=a_{2}+a_{3}\left(x-x_{2}\right)+\cdots+a_{n}\left(x-x_{2}\right) \cdots\left(x-x_{n}\right)$$ evaluando en $x=x_2$ $$ -a_{2}=\frac{1}{x_{2}-x_{1}}\left(\frac{y_{2}-y_{0}}{x_{2}-x_{0}}-\frac{y_{1}-y_{0}}{x_{1}-x_{0}}\right),$$ que podemos reescribir como -$$a_{2}=\frac{\frac{y_{2}-y_{1}}{x_{2}-x_{1}}-\frac{y_{1}-y_{0}}{x_{1}-x_{0}}}{x_{2}-x_{0}}.$$
  • -
- -
-
-
-
- -
- -
-
-

In summary -\begin{align} -a_{0}=& f\left[y_{0}\right] \equiv y_{0} \\ -a_{1}=& f\left[y_{0}, y_{1}\right] \equiv \frac{y_{1}-y_{0}}{x_{1}-x_{0}}\\ -a_{2}=&f\left[y_{0}, y_{1}, y_{2}\right] \equiv \frac{\frac{y_{2}-y_{1}}{x_{2}-x_{1}}-\frac{y_{1}-y_{0}}{x_{1}-x_{0}}}{x_{2}-x_{0}} -\end{align}

-

The key observation, by using the symmetry $f\left[y_{0}, y_{1}\right]=f\left[y_{1}, y_{0}\right]$, is -$$f\left[y_{0}, y_{1}, y_{2}\right]=\frac{f\left[y_{1}, y_{2}\right]-f\left[y_{0}, y_{1}\right]}{x_{2}-x_{0}}$$

- -
-
-
-
- -
- -
-
-

Allow us to definine the zeroth divided difference, $k=0$, of $x_i$ like

-$$D_0[x_i] \equiv f[x_i] \equiv f(x_i) = y_i$$

the first divided difference, $k=1$ of $x_i$ like

-$$D_1[x_i] \equiv f[x_i, x_{i+1}] \equiv \frac{f[x_{i+1}]-f[x_i]}{x_{i+1}-x_i}$$$$D_1[x_i] = \frac{D_{0}[x_{i+1}]-D_{0}[x_{i}]}{x_{i+1}-x_i} $$

the second divided difference, $k=2$ of $x_i$ like

-$$D_2[x_i]\equiv f[x_i,x_{i+1},x_{i+2}] \equiv \frac{f[x_{i+1},x_{i+2}]-f[x_i,x_{i+1}]}{x_{i+2}-x_{i}}$$$$D_2[x_i]=\frac{D_1[x_{i+1}]-D_1[x_i]}{x_{i+2}-x_{i}}$$

successively until the kth divided difference

-$$D_k[x_i] \equiv f[x_i, x_{i+1},\cdots, x_{i+k-1},x_{i+k}] \equiv \frac{f[x_{i+1},x_{i+2}\cdots, x_{i+k}]-f[x_i, x_{i+1},\cdots, x_{i+k-1}]}{x_{i+k}-x_i}$$$$D_k[x_i] = \frac{D_{k-1}[x_{i+1}]-D_{k-1}[x_{i}]}{x_{i+k}-x_i}$$

These expressions are the fundamental bricks for any interpolating method.

- -
-
-
-
- -
- -
-
- -
-
-
#Construction of a kth divided difference (recursive code)
-def D( i, k, Xn, Yn ):
-    #If k+i>N
-    if i+k>=len(Xn):
-        return 0
-    #Zeroth divided difference
-    elif k == 0:
-        return Yn[i]
-    #If higher divided difference
-    else:
-        return (D(i+1, k-1, Xn, Yn)-D(i, k-1, Xn, Yn))/(Xn[i+k]-Xn[i])
-
- -
-
-
- -
-
- -
- -
-
-

Example 2

-
-
-
-
- -
- -
-
-

As an example, Lagrange interpolation can be also derived by using divided differences, which is reached through the next equation:

-$$P_n(x) = D_0[x_0] + \sum_{k=1}^n D_k[x_0] (x-x_0) \cdots (x-x_{k-1})$$

Note this expression is by far easier to be manipulated analytically as we can know the coefficients of each order.

- -
-
-
-
- -
- -
-
-

Activity

-
-
-
-
- -
- -
-
-

-Using the previous expression and the defined function for divided differences, show both methods to calculate Lagrange interpolators are equivalents. -

- -
-
-
-
- -
- -
-
-
- -
-
-
-
- -
- -
-
-

Hermite Interpolation

-
-
-
-
- -
- -
-
-

From calculus we know that Taylor polynomials expand a function at a specific point $x_i$, being both functions (the original one and the Taylor function) exactly equal at any derivative-order at that point. Also, as mentioned before, a Lagrange polynomial, given a set of data points, passes through all those points at the same time. However if those points come from an unknown underlying function $f(x)$, the interpolant polynomial might (surely) differ from the real function at any superior derivative-order. So we have:

-
    -
  • Taylor polynomials are exact at any order, but that only remains true at a specific point.

    -
  • -
  • Lagrange polynomials pass through all points of a give dataset, but only at zeroth-order. Derivatives are not longer equal.

    -
  • -
-

Once established these differences, we can introduce Hermite polynomials just as a generalization of both, Taylor and Lagrange polynomials.

-

At first, Hermite polynomials can be approximated at any desired order at all the points, as long as one has all these information. However, for the sake of simplicity and without loss of generality, we shall assume Hermite polynomials equal to the real function at zeroth and first-derivative order.

-

Let's suppose a dataset $\{x_i\}_i$ for $i = 0,1,\cdots,n$ with the respective values $\{f(x_i)\}_i$ and $\{f'(x_i)\}_i$. If we assume two different polynomials to fit each set of data, i.e. a polynomial for $\{f(x_i)\}_i$ and another for $\{f'(x_i)\}_i$, we obtain $2n+2$ coefficients, however zeroth-order coefficients can be put together so finally there are $2n+1$ independet coefficients to be determined. In this case, we assign the respective Hermite polynimial as $H_{2n+1}(x)$.

- -
-
-
-
- -
- -
-
-

Derivation in terms of divided differences

-
-
-
-
- -
- -
-
-

Remembering the divided differences expression for a Lagrange polynomial

-$$P_n(x) = D_0[x_0] + \sum_{k=1}^n D_k[x_0] (x-x_0) \cdots (x-x_{k-1})$$

and by defining a new sequence $\{z_0, z_1, \cdots, z_{2n+1}\}$ such that

-$$z_{2i} = z_{2i+1} = x_i \mbox{ for } i = 0,1,\cdots, n$$

However, divided differences has to be modified in order to include first-order derivatives:

-

-

Note that $f[z_0,z_1]$ sould be originally

-$$f[z_0,z_1] = \frac{f[z_1]-f[z_0]}{z_1-z_0}$$

but replacing $z_0 = z_1 = x_0$ this would lead an indetermination. In order to solve this issue, this indertemination can be readily approximated to the derivative at $z_0$, so

-$$f[z_0,z_1] = f'(x_0)$$

or using the previously defined notation

-$$D_1[z_0] = f'(x_0)$$

Generally, for first-order divided differences we will have

-$$D_1[z_{2i}] = f'(x_i)$$$$D_1[z_{2i+1}] = D_1[x_i]$$

Higher order divided differences are calculated as usual.

-

Finally, the Hermite polynomial is built using the next expression

-$$H_{2n+1}(x) = D_0[z_0] + \sum_{k=1}^{2n+1} D_k[z_0] (x-z_0) \cdots (x-z_{k-1})$$ -
-
-
-
- -
- -
-
-

Example

-
-
-
-
- -
- -
-
- -
-
-
%pylab inline
-
- -
-
-
- -
-
- -
-
- -
-
Populating the interactive namespace from numpy and matplotlib
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
import pandas as pd
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
df=pd.read_csv('https://raw.githubusercontent.com/restrepo/ComputationalMethods/master/data/interpolation.csv')
-df
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
XY
03.08.0
110.06.5
221.33.0
-
-
- -
-
-
-
- -
-
- -
- -
-
-

Hermite interpolation

The recommend degree for the Hermite polynomial is $n-1$ where $n$ is the number of data points of the dataset

- -
-
-
-
- -
- -
-
- -
-
-
H=np.polynomial.hermite.Hermite.fit(df.X,df.Y,2)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
x=np.linspace(df.X.min(),df.X.max(),100)
-plt.plot(x,H(x))
-plt.plot(df.X,df.Y,'ro')
-plt.grid()
-plt.xlabel('$x$',size=15)
-plt.ylabel('$H(x)$',size=15)
-
- -
-
-
- -
-
- -
-
- - - -
-
Text(0,0.5,'$H(x)$')
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Example 3

-
-
-
-
- -
- -
-
-

Define a routine to calculate divided differences for Hermite polynomials.

- -
-
-
-
- -
- -
-
- -
-
-
#Construction of a kth divided difference for Hermite polynomials (recursive code)
-def Dh( j, k, Zn, Yn, Ypn ):
-    #If k+j>N
-    if j+k>=len(Zn):
-        return 0
-    #Zeroth divided difference
-    elif k == 0:
-        return Yn[j/2]
-    #First order divided difference (even indexes)
-    elif k == 1 and j%2 == 0:
-        return Ypn[j/2]
-    #If higher divided difference
-    else:
-        return (Dh(j+1, k-1, Zn, Yn, Ypn)-Dh(j, k-1, Zn, Yn, Ypn))/(Zn[j+k]-Zn[j])
-
- -
-
-
- -
-
- -
- -
-
-

**Activity**

-
-
-
-
- -
- -
-
-

-

Calculate a routine, using the previous program for divided differences, that computes the Hermite polynomial given a dataset.

-

Generate a set of $N$ points of the function $\sin^2(x)$ between $0$ and $2\pi$, including an array of $x$ positions, $y = f(x)$ and first derivative $y' = f'(x)$.

-

Show which polynomial gives the best approximation to the real function, Hermite or Lagrange polynomial.

-

</font>

-

-Solution:

-

nbviewer.ipython.org/github/sbustamante/ComputationalMethods/blob/master/activities/hermite-and-lagrange.ipynb -</font>

- -
-
-
-
- -
- -
-
-
- -
-
-
-
- - - - -
- \ No newline at end of file diff --git a/_build/features/ipython-notebooks.html b/_build/features/ipython-notebooks.html deleted file mode 100644 index 622cf4b..0000000 --- a/_build/features/ipython-notebooks.html +++ /dev/null @@ -1,433 +0,0 @@ ---- -interact_link: content/features/ipython-notebooks.ipynb -kernel_name: python3 -kernel_path: content/features -has_widgets: false -title: |- - Interactive editing with Jupyter -pagenum: 5 -prev_page: - url: /features/matplotlib.html -next_page: - url: /features/computer-arithmetics.html -suffix: .ipynb -search: com notebooks jupyter notebook github colab ipython org google markdown interactive text curves research blob master svg wikipedia web into step should t b restrepo computationalmethods ipynb src style upload computing python official page rich based code www en service cell example lissajous heading systems href material target parentimg assets badge alt open div wikimedia commons jupyterlogo px powerful designed programming support plots media easy new list item mathematica where document colleagues using viewer family problem wiki normally axis x y figures sin delta once nbviewer online dropbox drive gitlab float right img thumb png height interface multiple languages although - -comment: "***PROGRAMMATICALLY GENERATED, DO NOT EDIT. SEE ORIGINAL FILES IN /content***" ---- - -
-
Interactive editing with Jupyter
-
-
- -
-
-

Open In Colab

- -
-
-
-
- -
- -
-
-

Notebooks

- -
-
-
-
- -
- -
-
-

Open In Colab

-

Jupyter notebooks are a powerful web interface designed for interactive computing in multiple programming languages. Although it was initially designed for Python, its functionalities have quickly permeated other programming languagues. It have evolved from IPython, a replacement for the official Python shell in the console

-

It is worth mentioning the main author of IPython is Fernando Perez, a physicist graduate from the Universidad de Antioquia and currently Professor in University of California, Berkeley.

-

Official page

- -
-
-
-
- -
- -
-
-

Features

-

Jupyter provides a rich architecture for interactive computing with:

-
    -
  • Powerful interactive shells (terminal and Qt-based).
  • -
  • A browser-based notebook with support for code, text, mathematical expressions, inline plots and other rich media.
  • -
  • Support for interactive data visualization and use of GUI toolkits.
  • -
  • Flexible, embeddable interpreters to load into your own projects.
  • -
  • Easy to use, high performance tools for parallel computing.
  • -
- -
-
-
-
- -
- -
-
-

Jupyter Notebooks

-
-
-
-
- -
- -
-
-

Since 2011, Jupyter has incorporated a new funcionality called Notebooks. For

-
    -
  1. List item
  2. -
  3. List item
  4. -
-

those who know notebooks of Mathematica® and SAGE this feature may be familiar.

-

Official page Jupyter Notebooks

-

The Jupyter Notebook (or Jupyter lab) is a web-based interactive computational environment where you can combine code execution, text, mathematics, plots and rich media into a single document. These notebooks are normal files that can be shared with colleagues, converted to other formats such as HTML or PDF, etc. You can share any publicly available notebook by using the GitHub viewer service which will render it as a static web page. This makes it easy to give your colleagues a document they can read immediately without having to install anything.

-

Cell phone installation

- -
-
-
-
- -
- -
-
-

How to (step by step)

What is better than a step by step example when you want to introduce a new tool. Next it is shown a simple example of a IPython notebook for generating a family of Lissajous curves.

-
-

First, a suitable title for your notebook should be thought. For this, choose the style Heading 1 with # at the beggining.

-
-

Lissajous curves

Then, a brief statement of the problem to solve should be done. For this, you can use the Markdown style. A useful reference for formatting markdown text can be found here.

-
-

Lissajous curves are a family of parametric two-dimensional curves normally obtained when solving multi-harmonic systems, like a mass-spring systems with two springs in each axis (x and y) or some circuit systems. The figures are described with the following equations:

-

You can use LaTex format in a Markdown cell, for this you must use double $

-
-

$x(t) = A\sin(a t +\delta)$

-

$y(t) = B\sin(b t)$

-

where $A$ and $B$ are the amplitudes along each axis, $a$ and $b$ the angular frequencies and $\delta$ the relative phase.

-

It is possible to embed figures from internet into a Markdown cell simply by writing:

-
- -
![Some text](URL_to_figure)
-
-
-

Figure

-

Once established the problem, the first thing to do is to import all the libraries you should use for your calculations.

-
- -
-
-
-
- -
- -
-
- -
-
-
#This line is always necessary when you use matplotlib in a notebook, otherwise the figures will not appear.
-%pylab inline
-import matplotlib.pyplot as plt
-import numpy as np
-
- -
-
-
- -
-
- -
-
- -
-
Populating the interactive namespace from numpy and matplotlib
-
-
-
-
-
-
- -
-
- -
- -
-
-

You can create subsections and subsubsections using the styles Heading 2: with ##, and Heading 3: with ###

-
- -
-
-
-
- -
- -
-
-

Plotting some curves

-
-
-
-
- -
- -
-
-

Regarding coding, you can write Python code normally as if you were doing it in a text editor like emacs.

-
- -
-
-
-
- -
- -
-
- -
-
-
#Solutions
-def Lissajous( t, A=1.0, B=1.0, a=1.0, b=1.0, delta=0.0 ):
-    x = A*np.sin(a*t+delta)
-    y = B*np.sin(b*t)
-    return x, y
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
#Parameters to be sampled--------------------
-#delta
-Ndelta = 4   #Number of delta parameters
-Delta = np.linspace(0,np.pi,Ndelta)
-#Ratio c=a/b
-Nratio = 6  #Number of c parameters
-C = np.linspace(0,1,Nratio)
-#Time array
-T = np.linspace(0,40,1000)
-
-#Initializing plotting environment
-plt.figure( figsize=(4*Ndelta, 4*Nratio) )
-plt.subplot( Nratio, Ndelta, 1 )
-plt.plot()
-#Sweeping all figures
-for i in range( Ndelta ):
-    for j in range( Nratio ):
-        #Creating a subfigure with the current delta and ratio c
-        plt.subplot( Nratio, Ndelta, j*Ndelta+i+1 )
-        #Plotting this Lissajous curve
-        X, Y = Lissajous( T, b=C[j], delta=Delta[i] )
-        plt.title( "$\delta=$%1.2f\t$a/b=$%1.2f"%(Delta[i],C[j]) )
-        plt.plot( X, Y, linewidth=2 )
-
- -
-
-
- -
-
- -
-
- -
-
/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:19: MatplotlibDeprecationWarning: Adding an axes using the same arguments as a previous axes currently reuses the earlier instance.  In a future version, a new instance will always be created and returned.  Meanwhile, this warning can be suppressed, and the future behavior ensured, by passing a unique label to each axes instance.
-
-
-
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

References

-
-
-
-
- - - -
- -
-
-
- -
-
-
-
- -
- -
-
-

For this activity, you should obtain something like this.

- -
-
-
-
- -
- -
-
-

Viewing your notebook online

-
-
-
-
- -
- -
-
-

Once you have a notebook, you can upload it in some online storage service like Dropbox or Google drive or some repository service like GitHub or GitLab. In both GitHub and GitLab the notebooks are automatically displayed in their web interfaces. Also, you can put the link of your notebook directly into the IPython Notebook Viewer.

- -
-
-
-
- -
- -
-
- -
-
-
from IPython.display import display, Markdown, Latex, Image 
-Image(filename='./figures/nbviewer.png')
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
display(Markdown('*some markdown* $\phi={}$'.format(2)))
-
- -
-
-
- -
-
- -
-
- - -
-

some markdown $\phi=2$

- -
- -
-
-
-
- -
-
- - - - -
- \ No newline at end of file diff --git a/_build/features/least_action_minimization.html b/_build/features/least_action_minimization.html deleted file mode 100644 index b77007a..0000000 --- a/_build/features/least_action_minimization.html +++ /dev/null @@ -1,1320 +0,0 @@ ---- -redirect_from: - - "/features/least-action-minimization" -interact_link: content/features/least_action_minimization.ipynb -kernel_name: python3 -kernel_path: content/features -has_widgets: false -title: |- - Minimization for Least Action -pagenum: 15 -prev_page: - url: /features/Minimization.html -next_page: - url: /features/numerical-calculus.html -suffix: .ipynb -search: t x action m p frac l least function s end hbox xmin plt object plot points tx right com v obtained interpolation set range ts xp height xi ti polynomial delta approx left eqnarray return lagrange np initial final define small segment free fall data mass degree energy begin g interpolate between int value such ini random txx tt minimization div raw restrepo computationalmethods master leastaction geometry following www eftaylor motion fitted figure calculate align xx problem possible correct definition lagrangian rm d code throw vertically let using calculates steps solution activity cocalc zero curve check smooth polynomials step - -comment: "***PROGRAMMATICALLY GENERATED, DO NOT EDIT. SEE ORIGINAL FILES IN /content***" ---- - -
-
Minimization for Least Action
-
-
- -
-
-

Least Action with least squares minimization

-
-
-
-
- -
- -
-
-

Load modules

- -
-
-
-
- -
- -
-
- -
-
-
%pylab inline
-
- -
-
-
- -
-
- -
-
- -
-
Populating the interactive namespace from numpy and matplotlib
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
import numpy as np
-import scipy.optimize 
-import pandas as pd
-global g  
-g=9.8
-
- -
-
-
- -
-
- -
- -
-
-
- -

Geometry interpretation

Predict from initial conditions, rebuild physical path from initial and the final state.

-

Following the geometry theory developed here, we will try to define something called the Action for one small segment of the free fall motion in one-dimension.

-

For that we need the experimental data consisting on the height of an object of mass $m$ in free fall, and the height $x_i$, for each time $t_i$. This data would be fitted by a polynomial of degree two, as displayed in the figure for one of the fitted segments of the plot of $x$ as a function of $t$. We take the origin of the coordinates at ground level. For each segment we can calculate an average kinetic energy, $T$, and an averge potential energy, $V$, in the limit of $\Delta t=t_2-t_1$ small. From the figure

-\begin{align} -T_{12}=\frac12 m v^2\approx &\frac12 m\left(\frac{x_2-x_1}{t_2-t_1}\right)^2\,,& -V_{12}=mgh\approx& m g \frac{x_2+x_1}{2}\,. -\end{align}

We can then reformulate the problem of the free fall in the following terms. From all the possible curves that can interpolate the points $(t_1,x_1)$ and $(t_2,x_2)$, which is the correct one?.

-

The answer obtained by Euler can be obtained from the definition of the function "Lagrangian" -$$L(t)=T(t)-V(t)$$

-

We define the "Action" of one interpolating function between the points $(t_1,x_1)$ and $(t_2,x_2)$ as -$$S=\int_{t_1}^{t_2} L\, {\rm d}t $$

-

The result if that correct interpolation is the one that has a minumum value for the Action!

-

For one segment of the action between $(t_1,x_1)$, and $(t_2,x_2)$, with $\Delta t$ sufficiently small such that $L$ can be considered constant, we have -\begin{eqnarray} -S_1&=&\int_{t_1}^{t_2} L dt \\ -&\approx& \left[\frac12 m v^2-m g h \right]\Delta t\\ -&\approx& \left[\frac12 m\left(\frac{x_2-x_1}{t_2-t_1}\right)^2-m g \frac{x_2+x_1}{2} \right](t_2-t_1) -\end{eqnarray} -that corresponds to Eq. (11) of Am. J. Phys, Vol. 72(2004)478: http://www.eftaylor.com/pub/Symmetries&ConsLaws.pdf

- -
-
-
-
- -
- -
-
-

Code implementation

-
-
-
-
- -
- -
-
-

The Action

We define the Action $S$ such of an object of mass $m$ throw vertically upward from $x_{\hbox{ini}}$, such that $t_{\hbox{end}}$ seconds later the object return to a height $x_{\hbox{end}}$, as -\begin{eqnarray} -S&=&\int_{t_{\hbox{ini}}}^{t_{\hbox{end}}} L\, {\rm d}t \\ -&=&\sum_i L_i \Delta t -\end{eqnarray}

- -
-
-
-
- -
- -
-
- -
-
-
def S(x,tend=3.,m=0.2,xini=0.,xend=0.,g=9.8):
-    """
-    Calculate the Action of an object of of mass 'm' throw vertically upward from 
-       'xini', such that 'tend' seconds later the object return to a height 'xend'.
-       Delta t must be constant.
-       
-    The defaults units for S are J.s   
-    """
-    t=float(tend)
-    Dt=t/x[:-1].size
-    x=np.asarray(x)
-    #Fix initial and final point
-    x[0]=xini
-    x[-1]=xend
-    return ((0.5*m*(x[1:]-x[:-1])**2/Dt**2-0.5*m*g*(x[1:]+x[:-1]))*Dt).sum()
-
- -
-
-
- -
-
- -
- -
-
-

Least Action calculation

-
-
-
-
- -
- -
-
-

Problem: Let an object of mass $m=0.2$ Kg throw vertically updward and returning back to the same hand after 3 s. Find the function of distance versus time of least Action.

- -
-
-
-
- -
- -
-
-

If we denote the height at time $t_i$ as $x_i=x(t_i)$, we can calculate the action for any set of $x_i$ points with the inititial and final points fixed at $0\ $m.

-

Example: By using the previous definition, calculates the Action for 21 steps in time from $0$ at $3\ $s for an object that does not move at all

-

Solution:

- -
-
-
-
- -
- -
-
- -
-
-
x=np.zeros(21)
-S(x)
-
- -
-
-
- -
-
- -
-
- - - -
-
0.0
-
- -
-
-
-
- -
-
- -
- -
-
-

Activity: Brute force approach

-

Open the Activity notebook in CoCalc!

-

1) calculates the Action for 21 steps in time from $0$ at $3\ $s, for an object that at a random position in each time between zero and $15\ $m, but with the initial and final positions set to zero. Make the plot for the random curve.

- -
-
-
-
- -
- -
-
-

Let us divide the intervals in 21 parts:

- -
-
-
-
- -
- -
-
- -
-
-
#Initialize with the maximum possible value
-Smin=np.inf
-for i in range(100000):
-    #21 one random number between 0 and 15
-    x=np.random.uniform(0,15,21)
-    # Force the boundary conditions
-    x[0]=0
-    x[-1]=0
-    Sx=S(x)
-    if Sx<Smin:
-        #Get new minimum
-        Smin=Sx
-        xmin=x
-        print(Smin)
-
- -
-
-
- -
-
- -
-
- -
-
550.3493673339286
-459.61825206303354
-342.4644127733231
-331.459689578506
-225.01316485752167
-211.21468603608093
-196.71669612765731
-186.64743929364718
-154.74301469839858
-151.59615942111134
-99.39935405252346
-72.90890773801733
-70.46213681452232
-43.20057111692605
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
-
- -
- -
-
-

Check again the Acion, $S$, value for xmin

- -
-
-
-
- -
- -
-
-

2) Find the set of interpolation Lagrange polinomial that a set a points as smooth as possible

- -
-
-
-
- -
- -
-
- -
-
-
from scipy import interpolate
-
- -
-
-
- -
-
- -
- -
-
-

Assign a time, $t_i$ to each $x_i$ point in xmin

- -
-
-
-
- -
- -
-
- -
-
-
tx=np.linspace(0,3,len(xmin))
-
- -
-
-
- -
-
- -
- -
-
-

Complete the set of interpolation Lagrange polynomials: Change pe to the high value that allows for on smooth curve, and uncomment the next code and repeat as many times as required

- -
-
-
-
- -
- -
-
- -
-
-
p=[]
-plt.plot(tx,xmin,'r.')
-pi=0
-pe=3
-L=interpolate.lagrange(tx[pi:pe],xmin[pi:pe])
-txx=np.linspace(tx[pi],tx[pe-1])
-plt.plot(txx,L(txx))
-#Repeat to get a fit as smoot as possible
-#pi=pe-1
-#pe=8
-#L=interpolate.lagrange(tx[pi:pe],xmin[pi:pe])
-#txx=np.linspace(tx[pi],tx[pe-1])
-#plt.plot(txx,L(txx))
-
-plt.ylim(-1,20)
-plt.xlim(-0.1,3.3)
-
- -
-
-
- -
-
- -
-
- - - -
-
(-0.1, 3.3)
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

3) Built a step function for the full range each of the interpolation Lagrangian polynomial in each range

- -
-
-
-
- -
- -
-
- -
-
-
-
- -
- -
-
-

4) Build a step function with interpolate.interp1d

- -
-
-
-
- -
- -
-
-

5) Fit the points with a polynomial of degree 2

- -
-
-
-
- -
- -
-
- -
-
-
fig, (ax1, ax2) = plt.subplots(1, 2,figsize=(12,4))
-p=[]
-pi=0
-pe=21
-x1d=interpolate.interp1d(tx[pi:pe],xmin[pi:pe],kind=2)
-txx=np.linspace(tx[pi],tx[pe-1],1000)
-ax1.plot(tx,xmin,'r.')
-ax1.plot(txx,x1d(txx))
-ax1.set(xlim=(-0.1,3.3),ylim=(-1,20),
-        xlabel='$t$ [s]',ylabel='$x(t)$ (m)')
-
-ax2.plot(tx,xmin,'r.')
-ax2.plot(txx,x1d(txx))
-ax2.set(xlim=(0.5,1.3),ylim=(5.7,12),
-        xlabel='zoom in')
-
-fig.tight_layout(pad=4.0)
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
# Plot results 3) and 4) here
-
- -
-
-
- -
-
- -
- -
-
-

5) Compare the Action for xmin, some x obtained from the full range function obtained from the interpolation Lagrange polynomials, and some xP obtained from the degree 2 polynomial

- -
-
-
-
- -
- -
-
- -
-
-
S(xmin)
-
- -
-
-
- -
-
- -
-
- - - -
-
43.20057111692605
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#S for step function here
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
S(x1d(txx))
-
- -
-
-
- -
-
- -
-
- - - -
-
56.65688265854261
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#S for degree 2 function here
-
- -
-
-
- -
-
- -
- -
-
-

Which one is the one with the least action and why?

- -
-
-
-
- -
- -
-
-

Minimization

-
-
-
-
- -
- -
-
-

Function to find the least Action by using scipy.optimize.fmin_powell. It start from $\mathbf{x}=(x_{\hbox{ini}},0,0,\ldots,x_{\hbox{end}})$ and find the least action

- -
-
-
-
- -
- -
-
- -
-
-
import scipy.optimize as optimize
-def xfit(n,t=3.,m=0.2,xini=0.,xend=0.,ftol=1E-8):
-    '''Find the array of n (odd) components that minimizes the action S(x)
-
-    :Parameters:
-
-    n: odd integer 
-        dimension of the ndarray x that minimizes the action  S(x,t,m)
-    t,m: numbers
-       optional parameters for the action
-    ftol: number
-        acceptable relative error in S(x) for convergence.
-
-    :Returns: (x,xmax,Smin)
-    
-    x: ndarray
-        minimizer of the action S(x)
-        
-    xini:
-    
-    xend:
-
-    xmax: number
-        Maximum height for the object
-
-    Smin: number
-        value of function at minimum: Smin = S(x)
-    '''
-    t=float(t)
-    if n%2==0:
-        print ( 'x array must be odd')
-        sys.exit()
-  
-    x0=np.zeros(n)
-    a=optimize.fmin_powell(S,x0,args=(t,m,xini,xend),ftol=ftol,full_output=1)
-    x=a[0]
-    x[0]=xini;x[-1]=xend
-    xmax=np.sort(x)[-1]
-    Smin=a[1]
-    Dt=t/x[:-1].size #  t/(n-1)
-    return x,xmax,Smin,Dt
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
t=3.
-m=0.2
-y=xfit(21,t,m)
-x=y[0]
-xmax=y[1]
-Smin=y[2]
-Dt=y[3]
-tx=np.arange(0,t+Dt,Dt)
-
- -
-
-
- -
-
- -
-
- -
-
Optimization terminated successfully.
-         Current function value: -21.554977
-         Iterations: 28
-         Function evaluations: 5837
-
-
-
-
-
-
- -
-
- -
- -
-
-

Plot

-
-
-
-
- -
- -
-
- -
-
-
plt.plot(tx,x,label='$S_{\mathrm{min}}=$%.2f J.s' %Smin)
-plt.plot(tx,x,'ro')
-plt.ylabel('HEIGHT meters')
-plt.xlabel('TIME seconds')
-plt.title('Worldline of least action')
-plt.legend(loc='best')
-plt.grid()
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Check the equation of motion: -$$x(t)=-\frac{{1}}{{2}}gt^2+v_0t$$

- -
-
-
-
- -
- -
-
- -
-
-
P=poly1d ( np.polyfit(tx,x,2),variable='t' )
-print(P)
-
- -
-
-
- -
-
- -
-
- -
-
      2
--4.9 t + 14.7 t + 0.0001604
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
P(1.5)
-
- -
-
-
- -
-
- -
-
- - - -
-
11.025294114794459
-
- -
-
-
-
- -
-
- -
- -
-
-

Dynamics of the least action solution

-
-
-
-
- -
- -
-
-

Velocity

-
-
-
-
- -
- -
-
- -
-
-
v=(x[1:]-x[:-1])/Dt
-Dt=t/v[:-1].size
-tx=np.arange(0,t+Dt,Dt)
-plt.plot(tx,v)
-plt.plot(tx,v,'ro')
-plt.xlabel('TIME seconds')
-plt.ylabel('VELOCITY meter/seconds')
-plt.grid()
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Aceleration

-
-
-
-
- -
- -
-
- -
-
-
Dt=t/x[:-1].size
-a=(v[1:]-v[:-1])/Dt
-pa=plt.hist(a)
-plt.title('ACELERATION meter/second$^2$')
-
- -
-
-
- -
-
- -
-
- - - -
-
Text(0.5,1,'ACELERATION meter/second$^2$')
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Energy

-
-
-
-
- -
- -
-
- -
-
-
T=0.5*m*v**2
-V=0.5*m*g*(x[1:]+x[:-1])
-E=T+V
-print(np.round(E,2))
-
- -
-
-
- -
-
- -
-
- -
-
[21.56 21.56 21.56 21.56 21.56 21.56 21.55 21.55 21.56 21.56 21.56 21.56
- 21.56 21.56 21.56 21.55 21.55 21.56 21.56 21.55]
-
-
-
-
-
-
- -
-
- -
- -
-
-

Action

-
-
-
-
- -
- -
-
-

The Action is minimal in each interval!

- -
-
-
-
- -
- -
-
- -
-
-
SS=(T-V)*Dt
-SS
-
- -
-
-
- -
-
- -
-
- - - -
-
array([ 2.6176807 ,  1.45086655,  0.41339493, -0.49445999, -1.27239049,
-       -1.92031545, -2.4394347 , -2.82826668, -3.08743238, -3.21713111,
-       -3.21711685, -3.08747346, -2.82816485, -2.43888968, -1.9203943 ,
-       -1.27224487, -0.49433121,  0.41338257,  1.45064061,  2.61710336])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
import scipy.constants as sc
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
sc.hbar
-
- -
-
-
- -
-
- -
-
- - - -
-
1.0545718001391127e-34
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
print( 'S_MINIMUM={}  Joules*second = {} ħ'.format(
-      SS.sum(),
-      np.format_float_scientific(SS.sum()/sc.hbar,precision=0)
-      ) )
-
- -
-
-
- -
-
- -
-
- -
-
S_MINIMUM=-21.55497732876534  Joules*second = -2.e+35 ħ
-
-
-
-
-
-
- -
-
- - - - -
- \ No newline at end of file diff --git a/_build/features/linear-algebra-diagonalization.html b/_build/features/linear-algebra-diagonalization.html deleted file mode 100644 index ce6389f..0000000 --- a/_build/features/linear-algebra-diagonalization.html +++ /dev/null @@ -1,4580 +0,0 @@ ---- -interact_link: content/features/linear-algebra-diagonalization.ipynb -kernel_name: python3 -kernel_path: content/features -has_widgets: false -title: |- - Matriz diagonalization -pagenum: 21 -prev_page: - url: /features/linear-algebra.html -next_page: - url: /features/linear-algebra-extra.html -suffix: .ipynb -search: boldsymbol v u begin end matrix bmatrix m align left right operatorname c x lambda e dagger s diag t text array b alpha np vdots equation eigenvalues nu pmatrix rangle j cos sin where n mass pdf diagonalization theta delta cp w y such cdots eigenvectors example mathrm basis sqrt eigenvector order lambdai r symmetric associated therefore mu tau linalg check z d ldots l times prime rotation thetaw theorem exists lambdan arxiv org mixing terms mathcal com unitary equiv diagonal matrices python font color span h g eigenvalue not neutrino since proper zero redactivity obtain build previous angle - -comment: "***PROGRAMMATICALLY GENERATED, DO NOT EDIT. SEE ORIGINAL FILES IN /content***" ---- - -
-
Matriz diagonalization
-
-
- -
-
-

Matrix diagonalization

Open In Colab

- -
-
-
-
- -
- -
-
-

Theorem 1

If $\boldsymbol{A}$ is Hermitic, e.g: -\begin{align} -\boldsymbol{A}^\dagger =\boldsymbol{A}\,, -\end{align} -Then exists an unitary matrix $\boldsymbol{V}$ e.g: -\begin{align} -\boldsymbol{V}^{\ -1}=\boldsymbol{V}^\dagger \,, -\end{align} -such that -\begin{equation} - \boldsymbol{V}^\dagger\boldsymbol{A}\,\boldsymbol{V}=\boldsymbol{A}_{\text{diag}}\,, -\end{equation} -where -$\boldsymbol{A}_{\text{diag}}=\operatorname{diag}(\lambda_1,\lambda_2,\ldots \lambda_n)$ is the diagonalized mass matrix.

- -
-
-
-
- -
- -
-
-

Corollary 1

If $\boldsymbol{A}$ is symmetric, e.g: -\begin{align} -\boldsymbol{A}^{\operatorname{T}} =\boldsymbol{A}\,, -\end{align} -Then exists an ortogonal matrix $\boldsymbol{V}$, e.g: -\begin{align} -\boldsymbol{V}^{-1}=\boldsymbol{V}^{\operatorname{T}} \,, -\end{align} -such that -\begin{equation} - \boldsymbol{V}^{\operatorname{T}}\boldsymbol{A}\,\boldsymbol{V}=\boldsymbol{A}_{\text{diag}}\,, -\end{equation} -where -$\boldsymbol{A}_{\text{diag}}=\operatorname{diag}(\lambda_1,\lambda_2,\ldots \lambda_n)$ is the diagonalized mass matrix.

- -
-
-
-
- -
- -
-
-
- -
-
-
-
- -
- -
-
-

Eigenvector problem

Note that each eigenvector, corresponding to each column of the matrix, is associated to each eigenvalue -$$ -\boldsymbol{V}=\begin{bmatrix} -\boldsymbol{V}_1 \vdots \boldsymbol{V}_2\cdots \vdots \boldsymbol{V}_i \vdots \boldsymbol{V}_j\vdots\cdots \vdots \boldsymbol{V}_n -\end{bmatrix}. -$$ -where $\boldsymbol{V}_i$ is the $i$-th column of the matrix $\boldsymbol{V}$.

-

In this way, if we interchange the $i\leftrightarrow j$ columns of the diagonalization matrix $\boldsymbol{V}$, the order of the eigenvalues also change -$$ -\begin{bmatrix} -\boldsymbol{V}_1 \vdots \boldsymbol{V}_2\cdots \vdots \boldsymbol{V}_j \vdots \boldsymbol{V}_i\vdots\cdots \vdots \boldsymbol{V}_n -\end{bmatrix}^\dagger \boldsymbol{A} \begin{bmatrix} -\boldsymbol{V}_1 \vdots \boldsymbol{V}_2\cdots \vdots \boldsymbol{V}_j \vdots \boldsymbol{V}_i\vdots\cdots \vdots \boldsymbol{V}_n -\end{bmatrix}=\operatorname{diag}(\lambda_1,\lambda_2,\ldots,\lambda_j,\lambda_i,\ldots \lambda_n). -$$ -This property is very important because usually the diagonalizationn alghoritm gives not the desired ordering of the eigenvalues and eigenvectors. It is recommended to use the np.c_ method for the eigenvector reoirdering

-

However, the Theorem only guarantees existence. Tor really calculate the diagonalization matrix we must establish the eigenvector problem:

-

We can use the unitary propery to write -\begin{align} - \boldsymbol{V}\boldsymbol{V}^\dagger\boldsymbol{A}\,\boldsymbol{V}=&\boldsymbol{V}\boldsymbol{A}_{\text{diag}}\\ -\boldsymbol{A}\,\boldsymbol{V}=&\boldsymbol{V}\boldsymbol{A}_{\text{diag}}\,, -\end{align} -or -$$ -\boldsymbol{A}\begin{bmatrix} -\boldsymbol{V}_1 \vdots \boldsymbol{V}_2\cdots \vdots \boldsymbol{V}_n -\end{bmatrix} =\operatorname{diag}(\lambda_1,\lambda_2\ldots,\lambda_n)\begin{bmatrix} -\boldsymbol{V}_1 \vdots \boldsymbol{V}_2\cdots \vdots \boldsymbol{V}_n -\end{bmatrix}. -$$ -Therefore, the eigenvalue equation is just: -\begin{align} -%$$ - \boldsymbol{A}\,\boldsymbol{V}_i=&\lambda_i\boldsymbol{V}_i \nonumber\\ - \boldsymbol{A}\,\boldsymbol{V}_i-\lambda_i\boldsymbol{V}_i=&\boldsymbol{0} \nonumber\\ - (\boldsymbol{A}-\lambda_i \,\boldsymbol{I})\boldsymbol{V}_i=&\boldsymbol{0}\,, -%$$ -\end{align} -where $\boldsymbol{V}_i$ is the $i$-th column of the matrix $\boldsymbol{V}$, and $\boldsymbol{I}$ is the identity matrix.

-

To avoid the trivial solution $\boldsymbol{V}_i=\boldsymbol{0}$, we require that $\boldsymbol{A}-\lambda_i\, \boldsymbol{I}$ -does not have an inverse, or equivalently -$$\det( \boldsymbol{A}-\lambda_i\, \boldsymbol{I})=0\,.$$

- -
-
-
-
- -
- -
-
-

Example

From arXiv:2010.06458:

-

In the three flavor neutrino oscillation, the neutrino flavor states $\left|\nu_{\alpha}\right\rangle(\alpha=e, \mu, \tau)$ are linear superposition of mass eigenstates $\left|\nu_{j}\right\rangle(j=1,2,3):\left|\nu_{\alpha}\right\rangle=\Sigma_{j} U_{\alpha j}\left|\nu_{j}\right\rangle,$ where $U_{\alpha j}$ are the elements of the lepton mixing matrix known as PMNS (Pontecorvo-Maki-Nakagawa-Sakita) matrix such that -$$ -\left(\begin{array}{l} -\left|\nu_{e}\right\rangle \\ -\left|\nu_{\mu}\right\rangle \\ -\left|\nu_{\tau}\right\rangle -\end{array}\right)=\left(\begin{array}{lll} -U_{e 1} & U_{e 2} & U_{e 3} \\ -U_{\mu 1} & U_{\mu 2} & U_{\mu 3} \\ -U_{\tau 1} & U_{\tau 2} & U_{\tau 3} -\end{array}\right)\left(\begin{array}{l} -\left|\nu_{1}\right\rangle \\ -\left|\nu_{2}\right\rangle \\ -\left|\nu_{3}\right\rangle -\end{array}\right) -$$ -The time evolution follows $\left|\nu_{\alpha}(t)\right\rangle=\Sigma_{j} e^{-i E_{j} t} U_{\alpha j}\left|\nu_{j}\right\rangle,$ where $E_{j}$ is the energy associated with the mass eigenstates $\left|\nu_{i}\right\rangle$ This is a superposition state.

-
-

The observables associated to the three neutrinos are the entries of the $3\times 3$ unitary matrix $\boldsymbol{U}=\begin{pmatrix}\boldsymbol{U}_1\vdots\boldsymbol{U}_2\vdots\boldsymbol{U}_3\end{pmatrix}$, and the eigenvalues associated to each eigenvector $\boldsymbol{U}_1\to m_1$, $\boldsymbol{U}_2\to m_2$, $\boldsymbol{U}_3\to m_3$. The normal ordering is $m_1<m_2<m_3$. The unitary matrix can be parameterized in terms of three mixing angles, $\theta_{12}$ $\theta_{13}$, $\theta_{13}$, and a complex phase, $\delta_{\text{CP}}$, such that -$$ -\boldsymbol{U}=\left(\begin{array}{ccc} -1 & 0 & 0 \\ -0 & c_{23} & s_{23} \\ -0 & -s_{23} & c_{23} -\end{array}\right) \cdot\left(\begin{array}{ccc} -c_{13} & 0 & s_{13} e^{-i \delta_{\mathrm{CP}}} \\ -0 & 1 & 0 \\ --s_{13} e^{i \delta_{\mathrm{CP}}} & 0 & c_{13} -\end{array}\right) \cdot\left(\begin{array}{ccc} -c_{21} & s_{12} & 0 \\ --s_{12} & c_{12} & 0 \\ -0 & 0 & 1 -\end{array}\right), -$$ -where $c_{i j} \equiv \cos \theta_{i j}$ and $s_{i j} \equiv \sin \theta_{i j}$. Thus, we can write $\boldsymbol{U}$ as -$$ -\boldsymbol{U}=\left(\begin{array}{ccc}c_{12} c_{13} & s_{12} c_{13} & s_{13} e^{-i \delta_{\mathrm{CP}}} \\ -s_{12} c_{23}-c_{12} s_{13} s_{23} e^{i \delta_{\mathrm{CP}}} & c_{12} c_{23}-s_{12} s_{13} s_{23} e^{i \delta_{\mathrm{CP}}} & c_{13} s_{23} \\ s_{12} s_{23}-c_{12} s_{13} c_{23} e^{i \delta_{\mathrm{CP}}} & -c_{12} s_{23}-s_{12} s_{13} c_{23} e^{i \delta_{\mathrm{CP}}} & c_{13} c_{23}\end{array}\right) -$$ -so that -$$ -\boldsymbol{U}_1=\begin{pmatrix}U_{e1}\\ U_{\mu 1}\\ U_{\tau 1}\end{pmatrix}=\begin{pmatrix} -c_{12} c_{13} \\ --s_{12} c_{23}-c_{12} s_{13} s_{23} e^{i \delta_{\mathrm{CP}}} \\ -s_{12} s_{23}-c_{12} s_{13} c_{23} e^{i \delta_{\mathrm{CP}}} -\end{pmatrix},\qquad -\boldsymbol{U}_2=\begin{pmatrix}U_{e2}\\ U_{\mu 2}\\ U_{\tau 2}\end{pmatrix}=\begin{pmatrix} -s_{12} c_{13} \\ -c_{12} c_{23}-s_{12} s_{13} s_{23} e^{i \delta_{\mathrm{CP}}} \\ --c_{12} s_{23}-s_{12} s_{13} c_{23} e^{i \delta_{\mathrm{CP}}} -\end{pmatrix},\qquad -\boldsymbol{U}_3=\begin{pmatrix}U_{e3}\\ U_{\mu 3}\\ U_{\tau 3}\end{pmatrix}=\begin{pmatrix} -s_{13} e^{-i \delta_{\mathrm{CP}}} \\ -c_{13} s_{23} \\ -c_{13} c_{23} -\end{pmatrix} -$$

-

After decades of experimental efforts with thousands of millions of dollars in investment and two recent Nobel prizes, most of the parameters are already measured (see PDG22020 ):

-

IMAGE

-

where $\Delta m^2_{ij}=m^2_i-m^2_j$ is the squared mass difference between eigenvalues $i$ and $j$; and $\text{eV}$ is really $\text{eV}/c^2$ where $c$ is the speed of light in vacuum in natural units with $c=1$, and $1\ \text{eV}=1.602\,176\,6208(98)\times 10^{-19}\ \text{J}$.

- -
-
-
-
- -
- -
-
-

To a better measurement of $\delta_{CP}$ for example, a new large experiment called DUNE, and with a cost of around $\$1\,500$ million of dollars, is in construction in the United States -IMAGE

- -
-
-
-
- -
- -
-
-

Theorem 2: Singular value decomposition (SVD)

See SVD (where the Hermetique-conjugate is denoted with "*" instead that with "")

-

A general complex matrix $\boldsymbol{A}$ can be diagonalized by a bi-diagonal transformation such that -\begin{equation} - \boldsymbol{V}^\dagger\boldsymbol{A}\,\boldsymbol{U}=\boldsymbol{A}_{\text{diag}}\,, -\end{equation} -where -$\boldsymbol{A}_{\text{diag}}=\operatorname{diag}(\lambda_1,\lambda_2,\ldots \lambda_n)$ is the diagonalized mass matrix.

-

Demostration

\begin{align} - \boldsymbol{A}_{\text{diag}}=&\boldsymbol{V}^\dagger\boldsymbol{A}\,\boldsymbol{U}\\ - \boldsymbol{A}_{\text{diag}}\boldsymbol{A}_{\text{diag}}^\dagger=&\boldsymbol{V}^\dagger\boldsymbol{A}\,\boldsymbol{U} - \left(\boldsymbol{V}^\dagger\boldsymbol{A}\,\boldsymbol{U}\right)^\dagger\\ - =&\boldsymbol{V}^\dagger\boldsymbol{A}\,\boldsymbol{U} - \left( \boldsymbol{U}^\dagger \boldsymbol{A}^\dagger\,\boldsymbol{V}\right)\\ - =&\boldsymbol{V}^\dagger - \left( \boldsymbol{A} \boldsymbol{A}^\dagger\,\right) \boldsymbol{V}\,.\\ -\end{align}

Since $\boldsymbol{A} \boldsymbol{A}^\dagger$ is hermitic and $\boldsymbol{A} \boldsymbol{A}^\dagger$ is diagonal, then in fact there exists an unitary matrix $\boldsymbol{V}$. Similarly there exists an unitary matrix $\boldsymbol{U}$ which diagonalizes $\boldsymbol{A}^\dagger \boldsymbol{A}$

- -
-
-
-
- -
- -
-
-

Scipy implementation

The implementation in scipy is based in the inverted relation -\begin{align} - \boldsymbol{V}^\dagger\boldsymbol{A}\,\boldsymbol{U}=&\boldsymbol{A}_{\text{diag}}\\ - \boldsymbol{V}\boldsymbol{V}^\dagger\boldsymbol{A}\,\boldsymbol{U}\boldsymbol{U}^\dagger=&\boldsymbol{V}\boldsymbol{A}_{\text{diag}}\boldsymbol{U}^\dagger\\ - \boldsymbol{A}=&\boldsymbol{V}\boldsymbol{A}_{\text{diag}}\boldsymbol{U}^\dagger\,. -\end{align}

-

The implementation is trough the module scipy.linalg.svd:

-
V,Adiag,Udagger=linalg.svd(A)
-
- -
-
-
-
- -
- -
-
-

Eigenvectors and eigenvalues

If we make -$$ \boldsymbol{U}=[\boldsymbol{U}_1\vdots\boldsymbol{U}_2\vdots\cdots\vdots\boldsymbol{U}_n], \qquad \boldsymbol{V}=[\boldsymbol{V}_1\vdots\boldsymbol{V}_2\vdots\cdots\vdots\boldsymbol{V}_n] $$

-

We know that there exists a bi-diagonal transformación such that -\begin{equation} -%$$ - \boldsymbol{A}\,\boldsymbol{U}=\boldsymbol{V}\boldsymbol{A}_{\text{diag}} -\end{equation} -\begin{equation} - \boldsymbol{A}\,\boldsymbol{U}_i=\lambda_i\boldsymbol{V}_i -%$$ -\end{equation} -not sum upon $i$. Here

-
    -
  • $\lambda_i$ are called eigenvalues
  • -
  • $V_i$ and $U_i$ are the eigenvectors
  • -
- -
-
-
-
- -
- -
-
-

We can use this to check the proper order of the eigenvalues

- -
-
-
-
- -
- -
-
-

Transformation of a linear system

We start again with the matrix equation, capitol bold letters denotes matrices -\begin{equation} - \boldsymbol{A}\boldsymbol{X}=\boldsymbol{B}\,, -\end{equation} -where $\boldsymbol{A}$ is an $n \times n$ matrix.

-

We know that there exists a bi-diagonal transformación such that -\begin{equation} - \boldsymbol{V}^\dagger\boldsymbol{A}\,\boldsymbol{U}=\boldsymbol{A}_{\text{diag}} -\end{equation} -So, by doing standard operations we have -\begin{align} - \boldsymbol{V}^\dagger \boldsymbol{A} \boldsymbol{U} \boldsymbol{U}^\dagger \boldsymbol{X}=& \boldsymbol{V}^\dagger \boldsymbol{B}\\ - \left( \boldsymbol{V}^\dagger \boldsymbol{A} \boldsymbol{U} \right) - \left( \boldsymbol{U}^\dagger \boldsymbol{X}\right)=& \boldsymbol{V}^\dagger \boldsymbol{B}\\ - \boldsymbol{A}_{\text{diag}} \boldsymbol{X}'=&\boldsymbol{B}'\,, -\end{align} -where -\begin{align} - \boldsymbol{X}'=& \boldsymbol{U}^\dagger \boldsymbol{X}\,, & \boldsymbol{B}'=& \boldsymbol{V}^\dagger \boldsymbol{B}\,, -\end{align} -or -\begin{align} - \boldsymbol{X}=& \boldsymbol{U}\boldsymbol{X}'\,, & \boldsymbol{B}=& \boldsymbol{V}\boldsymbol{B}'\,. -\end{align}

-

If $\boldsymbol{A}_{\text{diag}}=\operatorname{diag}(\lambda_1,\lambda_2,\ldots \lambda_n)$, $\boldsymbol{X}^{\operatorname{T}}=\begin{pmatrix}x_1 & x_2 &\cdots & x_n\end{pmatrix}^{\operatorname{T}}$ and $\boldsymbol{B}^{\operatorname{T}}=\begin{pmatrix}b_1& b_2 &\cdots & b_n\end{pmatrix}^{\operatorname{T}}$, -the solution of the system is given by -\begin{equation} -\lambda_i x'_i=b_i'\,. -\end{equation}

-

Note that -\begin{align} - \boldsymbol{X}'=&\boldsymbol{A}_{\text{diag}}^{-1}\boldsymbol{B}'\,, -\end{align} -and the final solution is -\begin{align} - \boldsymbol{X}=&U \boldsymbol{X}'\\ - =&U\boldsymbol{A}_{\text{diag}}^{-1}V^\dagger \boldsymbol{B}\,, -\end{align} -Therefore -$$A^{-1}=U\boldsymbol{A}_{\text{diag}}^{-1}V^\dagger$$

- -
-
-
-
- -
- -
-
-

Example

-
-
-
-
- -
- -
-
-

A suitable way to introduce this method is applying it to some basic problem. To do so, let's take the result of the Example 1:

-$$ \begin{bmatrix} -5 & -4 & 0 \\ --4 & 7 & -3 \\ -0 & -3 & 5 -\end{bmatrix} -\begin{bmatrix} -x_{1} \\ -x_{2} \\ -x_{3} -\end{bmatrix} = -\begin{bmatrix} -1 \\ -0 \\ --2 -\end{bmatrix} -$$

As the matrix is symmetric $\boldsymbol{V}=\boldsymbol{U}$ and $\boldsymbol{U}^\dagger=\boldsymbol{U}^{\operatorname{T}}$

- -
-
-
-
- -
- -
-
- -
-
-
import numpy as np
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
M1=np.array([[5,-4,0],
-             [-4,7,-3],
-             [0,-3,5]])
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
A=M1
-A
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[ 5, -4,  0],
-       [-4,  7, -3],
-       [ 0, -3,  5]])
-
- -
-
-
-
- -
-
- -
- -
-
-

Check if all eigenvalues are different from zero:

- -
-
-
-
- -
- -
-
- -
-
-
np.linalg.det(A)
-
- -
-
-
- -
-
- -
-
- - - -
-
49.99999999999999
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
B=np.c_[ [1,0,-2]  ]
-B
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[ 1],
-       [ 0],
-       [-2]])
-
- -
-
-
-
- -
-
- -
- -
-
-

Also as

-
B=np.array([[1],[0],[-2]])
-#or
-B=np.reshape(  [1,0,-2],(3,1) )
-
- -
-
-
-
- -
- -
-
-

Theorem 1 in numpy

-
-
-
-
- -
- -
-
- -
-
-
λ,V=np.linalg.eig( A )
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
A_diag=np.diag(λ)
-A_diag
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[11.09901951,  0.        ,  0.        ],
-       [ 0.        ,  0.90098049,  0.        ],
-       [ 0.        ,  0.        ,  5.        ]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
V
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[-5.07191124e-01, -6.18673713e-01, -6.00000000e-01],
-       [ 7.73342141e-01, -6.33988906e-01,  1.91548674e-16],
-       [-3.80393343e-01, -4.64005285e-01,  8.00000000e-01]])
-
- -
-
-
-
- -
-
- -
- -
-
-

We first check the proper order of the diagonalization

- -
-
-
-
- -
- -
-
- -
-
-
np.dot(  np.dot( V.transpose(),A  ), V).round(14)
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[11.09901951,  0.        ,  0.        ],
-       [ 0.        ,  0.90098049,  0.        ],
-       [ 0.        ,  0.        ,  5.        ]])
-
- -
-
-
-
- -
-
- -
- -
-
-

Since

- -
-
-
-
- -
- -
-
- -
-
-
V
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[-5.07191124e-01, -6.18673713e-01, -6.00000000e-01],
-       [ 7.73342141e-01, -6.33988906e-01,  1.91548674e-16],
-       [-3.80393343e-01, -4.64005285e-01,  8.00000000e-01]])
-
- -
-
-
-
- -
-
- -
- -
-
-

The final solution is:

- -
-
-
-
- -
- -
-
- -
-
-
A_diag_inv=np.diag(1/λ)
-A_diag_inv
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[0.09009805, 0.        , 0.        ],
-       [0.        , 1.10990195, 0.        ],
-       [0.        , 0.        , 0.2       ]])
-
- -
-
-
-
- -
-
- -
- -
-
-

check with np.linalg.inv(A_diag)

- -
-
-
-
- -
- -
-
- -
-
-
X=np.dot( np.dot( np.dot( V, np.diag(1/λ) ),V.transpose() ),B)
-X
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[ 0.04],
-       [-0.2 ],
-       [-0.52]])
-
- -
-
-
-
- -
-
- -
- -
-
-

Activity: Usar np.lingalg.solve

- -
-
-
-
- -
- -
-
- -
-
-
B.transpose()[0]
-
- -
-
-
- -
-
- -
-
- - - -
-
array([ 1,  0, -2])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
np.linalg.solve(A,B.transpose()[0])
-
- -
-
-
- -
-
- -
-
- - - -
-
array([ 0.04, -0.2 , -0.52])
-
- -
-
-
-
- -
-
- -
- -
-
-

We can now check some properties.

-
    -
  • Obtain $\theta_{12}$ for $\lambda_1<\lambda_2<\lambda_3$
  • -
- -
-
-
-
- -
- -
-
- -
-
-
V
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[-5.07191124e-01, -6.18673713e-01, -6.00000000e-01],
-       [ 7.73342141e-01, -6.33988906e-01,  1.91548674e-16],
-       [-3.80393343e-01, -4.64005285e-01,  8.00000000e-01]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
np.c_[ V[: ,0] ]
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[-0.50719112],
-       [ 0.77334214],
-       [-0.38039334]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
A_diag[0,0],λ[0]
-
- -
-
-
- -
-
- -
-
- - - -
-
(11.099019513592784, 11.099019513592784)
-
- -
-
-
-
- -
-
- -
- -
-
-

We define the eigenvector $V_i$ as

- -
-
-
-
- -
- -
-
- -
-
-
V0=np.c_[ V[:,0] ]
-V1=np.c_[ V[:,1] ]
-V2=np.c_[ V[:,2] ]
-display(V0)
-display(V1)
-V2
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[-0.50719112],
-       [ 0.77334214],
-       [-0.38039334]])
-
- -
-
-
-
- - - -
-
array([[-0.61867371],
-       [-0.63398891],
-       [-0.46400528]])
-
- -
-
-
-
- - - -
-
array([[-6.00000000e-01],
-       [ 1.91548674e-16],
-       [ 8.00000000e-01]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
print('{} =\n{}'.format( np.dot(A,V0),λ[0]*V0 ) )
-
- -
-
-
- -
-
- -
-
- -
-
[[-5.62932419]
- [ 8.58333952]
- [-4.22199314]] =
-[[-5.62932419]
- [ 8.58333952]
- [-4.22199314]]
-
-
-
-
-
-
- -
-
- -
- -
-
-

Check: $ A V_i=\lambda_i V_i$

-

Which means the eigenvalue associated to the "operator" $A$ acting on the eigenvector $V_1$

- -
-
-
-
- -
- -
-
- -
-
-
print('{} =\n{}'.format( np.dot(A,V1),λ[1]*V1 ) )
-
- -
-
-
- -
-
- -
-
- -
-
[[-0.55741294]
- [-0.57121163]
- [-0.41805971]] =
-[[-0.55741294]
- [-0.57121163]
- [-0.41805971]]
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
print('{} =\n{}'.format( np.dot(A,V2).round(14),
-                         (λ[2]*V2).round(14) ) )
-
- -
-
-
- -
-
- -
-
- -
-
[[-3.]
- [ 0.]
- [ 4.]] =
-[[-3.]
- [ 0.]
- [ 4.]]
-
-
-
-
-
-
- -
-
- -
- -
-
-

The diagonalization matrix can be rebuild from the eigenvectors

- -
-
-
-
- -
- -
-
- -
-
-
V
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[-5.07191124e-01, -6.18673713e-01, -6.00000000e-01],
-       [ 7.73342141e-01, -6.33988906e-01,  1.91548674e-16],
-       [-3.80393343e-01, -4.64005285e-01,  8.00000000e-01]])
-
- -
-
-
-
- -
-
- -
- -
-
-

is rebuild with

- -
-
-
-
- -
- -
-
- -
-
-
U=np.c_[ V0,V1,V2]
-
- -
-
-
- -
-
- -
- -
-
-

or with: np.hstack((V0,V1,V2))

- -
-
-
-
- -
- -
-
-

Note that a sign of an egigenvalues can be changed:

- -
-
-
-
- -
- -
-
- -
-
-
U=np.c_[ V0,-V1,V2]
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
np.dot(  np.dot( U.transpose(),A  ), U).round(14)
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[11.09901951, -0.        ,  0.        ],
-       [-0.        ,  0.90098049, -0.        ],
-       [ 0.        , -0.        ,  5.        ]])
-
- -
-
-
-
- -
-
- -
- -
-
-

Eigenvector reordering

-
-
-
-
- - - -
- -
-
-

We can use this to check the proper order of the eigenvalues

- -
-
-
-
- -
- -
-
- -
-
-
U=np.c_[ V1,V2,V0]
-np.dot(  np.dot( U.transpose(),A  ), U).round(14)
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[ 0.90098049,  0.        ,  0.        ],
-       [ 0.        ,  5.        ,  0.        ],
-       [ 0.        ,  0.        , 11.09901951]])
-
- -
-
-
-
- -
-
- -
- -
-
-

The order of eigenvalues can now be changed by changing the order of the eigenvectors and redifining the diagonalization matrix. For example, from small to large. We define first the eigenvalues

- -
-
-
-
- -
- -
-
- -
-
-
U
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[-6.18673713e-01, -6.00000000e-01, -5.07191124e-01],
-       [-6.33988906e-01,  1.91548674e-16,  7.73342141e-01],
-       [-4.64005285e-01,  8.00000000e-01, -3.80393343e-01]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
θ_12=np.arctan( U[0,1]/U[0,0] )
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
θ_12, θ_12*180/np.pi
-
- -
-
-
- -
-
- -
-
- - - -
-
(0.7700763823614476, 44.122126612013574)
-
- -
-
-
-
- -
-
- -
- -
-
-

Generalization of the reordering

- -
-
-
-
- -
- -
-
- -
-
-
np.sort?
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
np.sort( λ)
-
- -
-
-
- -
-
- -
-
- - - -
-
array([ 0.90098049,  5.        , 11.09901951])
-
- -
-
-
-
- -
-
- -
- -
-
-

To reverse the order

- -
-
-
-
- -
- -
-
- -
-
-
np.sort( λ)[::-1]
-
- -
-
-
- -
-
- -
-
- - - -
-
array([11.09901951,  5.        ,  0.90098049])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
λ
-
- -
-
-
- -
-
- -
-
- - - -
-
array([ 11.09901951,   0.90098049,   5.        ])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
index=np.abs(λ).argsort()
-index
-
- -
-
-
- -
-
- -
-
- - - -
-
array([1, 2, 0])
-
- -
-
-
-
- -
-
- -
- -
-
-

can be implemented in general with a comprehensive list

- -
-
-
-
- -
- -
-
- -
-
-
V
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[-5.07191124e-01, -6.18673713e-01, -6.00000000e-01],
-       [ 7.73342141e-01, -6.33988906e-01,  1.91548674e-16],
-       [-3.80393343e-01, -4.64005285e-01,  8.00000000e-01]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
np.c_[ tuple( [ np.c_[V[:,i]]    for i in range(3) ] ) ]
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[-5.07191124e-01, -6.18673713e-01, -6.00000000e-01],
-       [ 7.73342141e-01, -6.33988906e-01,  1.91548674e-16],
-       [-3.80393343e-01, -4.64005285e-01,  8.00000000e-01]])
-
- -
-
-
-
- -
-
- -
- -
-
-

Changing the order to index

- -
-
-
-
- -
- -
-
- -
-
-
U=np.c_[ tuple( [ np.c_[V[:,i]]    for i in np.abs(λ).argsort() ] ) ]
-U
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[-6.18673713e-01, -6.00000000e-01, -5.07191124e-01],
-       [-6.33988906e-01,  1.91548674e-16,  7.73342141e-01],
-       [-4.64005285e-01,  8.00000000e-01, -3.80393343e-01]])
-
- -
-
-
-
- -
-
- -
- -
-
-

or:

-
n=3
-U=np.hstack( [ np.reshape( V[:,i], (n,1) ) for i in index   ] )
-
- -
-
-
-
- -
- -
-
- -
-
-
np.dot(  np.dot( U.transpose(),A  ), U).round(14)
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[ 0.90098049,  0.        ,  0.        ],
-       [ 0.        ,  5.        ,  0.        ],
-       [ 0.        ,  0.        , 11.09901951]])
-
- -
-
-
-
- -
-
- -
- -
-
-

__Activity__: Build a function that diagonalize with increasing order in the eigenvalues as a replacement of np.linalg.eig

-
def argeig(A):
-    l,V=np.linalg.eig(A)
-    ....
-    return argl, argV
-
- -
-
-
-
- -
- -
-
-

and check that

- -
-
-
-
- -
- -
-
- -
-
-
-
- -
- -
-
-
#1.
-λ,V=argeig(A)
-λ,V
-Out[1]:
-(array([ 0.90098049,  5.        , 11.09901951]),
- array([[-6.18673713e-01, -6.00000000e-01, -5.07191124e-01],
-        [-6.33988906e-01,  1.91548674e-16,  7.73342141e-01],
-        [-4.64005285e-01,  8.00000000e-01, -3.80393343e-01]]))
-
- -
-
-
-
- -
- -
-
-
#2.
-np.dot(  np.dot( V.transpose(),A  ), V).round(14)
-Out[1]:
-array([[ 0.90098049,  0.        ,  0.        ],
-       [ 0.        ,  5.        ,  0.        ],
-       [ 0.        ,  0.        , 11.09901951]])
-
- -
-
-
-
- -
- -
-
-
#3.
-print( np.linalg.det(A- λ[0]*np.identity(3) ) )
-print( np.linalg.det(A- λ[1]*np.identity(3) ) )
-np.linalg.det(A- λ[2]*np.identity(3) )
-
- -
-
-
-
- -
- -
-
-

General matrix

-
-
-
-
- -
- -
-
- -
-
-
import numpy as np
-from scipy import linalg
-
- -
-
-
- -
-
- -
- -
-
-

Example:

- -
-
-
-
- -
- -
-
- -
-
-
#A=np.array([[ 2.5       ,  6.92820323],
-#            [-4.33012702,  4.        ]])
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
A=np.array([[ 6.66674644,  3.13121253],
-            [-0.23343505,  5.8902893 ]])
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
from scipy import linalg
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
V,diag,Udagger=linalg.svd(A)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
U=Udagger.transpose().conjugate()
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
np.dot( np.dot( V.transpose().conjugate(),A    ), U).round(14)
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[8., 0.],
-       [0., 5.]])
-
- -
-
-
-
- -
-
- -
- -
-
-

This is important to stablish that the eigenvectors are determined until ordering and permutations

- -
-
-
-
- -
- -
-
- -
-
-
V
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[-0.8660254, -0.5      ],
-       [-0.5      ,  0.8660254]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
U
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[-0.70710678, -0.70710678],
-       [-0.70710678,  0.70710678]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
np.dot( np.transpose(U),U ).round(14)
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[ 1., -0.],
-       [-0.,  1.]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
def orthogonal(θ):
-    return np.array( [[np.cos(θ) ,np.sin(θ)],
-                      [-np.sin(θ),np.cos(θ)]]   )
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
Vp=orthogonal(np.pi/3)
-Vp
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[ 0.5      ,  0.8660254],
-       [-0.8660254,  0.5      ]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
VV=np.c_[ -V[:,1],-V[:,0]  ]
-VV
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[ 0.5      ,  0.8660254],
-       [-0.8660254,  0.5      ]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
Up=orthogonal(np.pi/4)
-Up
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[ 0.70710678,  0.70710678],
-       [-0.70710678,  0.70710678]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
UU=np.c_[ -U[:,1],-U[:,0]  ]
-UU
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[ 0.70710678,  0.70710678],
-       [-0.70710678,  0.70710678]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
np.dot( np.dot( VV.transpose().conjugate(),A    ), UU).round(14)
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[5., 0.],
-       [0., 8.]])
-
- -
-
-
-
- -
-
- - - -
- -
-
-

__Activity__: Solve the system -$$ \boldsymbol{A} \boldsymbol{x}=\boldsymbol{B}$$ -for the previous $ \boldsymbol{A}$ matrix and -$$\boldsymbol{B}=\begin{bmatrix} - 1\\ - -4\\ - \end{bmatrix}$$

- -
-
-
-
- -
- -
-
-

Interpretations of Theorem 2

-
-
-
-
- -
- -
-
-

Single Diagonalization matrix

In Theorem 2 establishes a unique set of a matrix $A$ with its eigenvalues and eigenvectors. However, for a fixed set of eigenvalues and eigenvectors we can have several possibilities of $A'$ matrices. For example, if we fix $U'=\boldsymbol{1}$ -\begin{equation} - {V'}^\dagger \boldsymbol{A'}=\boldsymbol{A}_{\text{diag}}\,, -\end{equation} -so that -\begin{equation} - \boldsymbol{A}'=V'\boldsymbol{A}_{\text{diag}} -\end{equation}

-

Therefore: Under this conditions, for a fixed set of eigenvalues and eigenvectors (associated to the matrix $V'$) there is a unique $A'$ matrix

-

Example -Let $V'=U^{\operatorname{T}} V$ in the previous example. Find the matrix $A'$ which gives rise to the same eigenvalues

- -
-
-
-
- -
- -
-
- -
-
-
Adiag=np.array( [[5,0],
-                 [0,8]] )
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
Vp=np.dot( orthogonal(np.pi/4).transpose(),orthogonal(np.pi/3) )
-Vp
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[ 0.96592583,  0.25881905],
-       [-0.25881905,  0.96592583]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
Ap=np.dot( Vp,np.array( Adiag ) )
-Ap
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[ 4.82962913,  2.07055236],
-       [-1.29409523,  7.72740661]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
np.dot( Vp.transpose(),Ap).round(14)
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[5., 0.],
-       [0., 8.]])
-
- -
-
-
-
- -
-
- -
- -
-
-

Finally, we can use the full procedure of hermitic matrices to obtain the bidiagonal matrices $U,V$

-

Example: -Diagonalize the matrix $A$ by using the Theorem 1 instead

- -
-
-
-
- -
- -
-
- -
-
-
A=np.array([[ 6.66674644,  3.13121253],
-            [-0.23343505,  5.8902893 ]])
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
np.dot( A,A.transpose() )
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[54.25      , 16.88749537],
-       [16.88749537, 34.74999996]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
np.dot( A.transpose(),A )
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[44.50000002, 19.50000001],
-       [19.50000001, 44.49999995]])
-
- -
-
-
-
- -
-
- -
- -
-
-

→ is obtained with <ALT GR>+i or, similarly: ↓←

- -
-
-
-
- -
- -
-
- -
-
-
λ2,V=np.linalg.eig( np.dot( A,A.transpose() ) )
-print(λ2,'→',np.sqrt(λ2))
-#V=np.c_[ -V[:,0],V[:,0]  ]
-V
-
- -
-
-
- -
-
- -
-
- -
-
[63.99999999 24.99999997] → [8. 5.]
-
-
-
-
-
-
- - - -
-
array([[ 0.8660254, -0.5      ],
-       [ 0.5      ,  0.8660254]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
λ2p,U=np.linalg.eig( np.dot( A.transpose(),A ) )
-print(np.sqrt(λ2))
-U
-
- -
-
-
- -
-
- -
-
- -
-
[8. 5.]
-
-
-
-
-
-
- - - -
-
array([[ 0.70710678, -0.70710678],
-       [ 0.70710678,  0.70710678]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
np.dot( np.dot( V.transpose(),A ), U ).round(14)
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[ 8., -0.],
-       [ 0.,  5.]])
-
- -
-
-
-
- -
-
- -
- -
-
-

__Actividad:__ cambiar el orden de los autovectores para obtener un orden ascendente en los autovalores

- -
-
-
-
- -
- -
-
-

Mixed terms

-
-
-
-
- -
- -
-
-

Let: -\begin{align} -X' = -\begin{bmatrix} -B \\ -W \\ -\end{bmatrix} -\end{align}

-

Consider the quadratic equation -\begin{align} -X^{\prime\operatorname{T}} M X^\prime=& \begin{bmatrix} -B & W -\end{bmatrix} -\begin{bmatrix} -M_{11} & M_{12} \\ -M_{12} & M_{22} \\ -\end{bmatrix} -\begin{bmatrix} -B \\ -W \\ -\end{bmatrix}\\ -=& -\begin{bmatrix} -B & W -\end{bmatrix} -\begin{bmatrix} -M_{11}B + M_{12}W \\ -M_{12}B + M_{22}W \\ -\end{bmatrix}\\ -=& -B( M_{11}B + M_{12}W)+ W ( M_{12}B + M_{22}W )\\ -=&M_{11} B^2 + 2M_{12} BW+ M_{22} W^2\,. -\end{align} -The quadratic equation is in terms of: $M_{11}$, $M_{12}$ y $M_{22}$

-

We can simplify this expression if we change to a new basis -$$ -X=\begin{bmatrix} -A\\ -Z -\end{bmatrix} -$$ -in which $M$ is diagonal, in such a case the crossed term would disappear. -The rotation from $X'\to X$ is defined by -\begin{align} -X'= -\begin{bmatrix} -B\\ -W -\end{bmatrix}\equiv -\begin{bmatrix} -\cos\theta & \sin\theta\\ --\sin\theta & \cos\theta -\end{bmatrix} -\begin{bmatrix} -A\\ -Z -\end{bmatrix}= -V X -\end{align} -where $V$ is the rotation matrix -$$ -V=\begin{bmatrix} -\cos\theta & \sin\theta\\ --\sin\theta & \cos\theta -\end{bmatrix}. -$$ -Therefore -\begin{align} -X\equiv -\begin{bmatrix} -A\\ -Z -\end{bmatrix}=V^{\operatorname{T}} X' \to X^{\operatorname{T}}= X^{\prime\operatorname{T}} V\,, -\end{align}

-

In the new basis -\begin{align} -X^{\prime\operatorname{T}} M X^\prime=&X^{\prime\operatorname{T}}V V^{\operatorname{T}} M V V^{\operatorname{T}} X^\prime\\ -=&(X^{\prime\operatorname{T}}V) (V^{\operatorname{T}} M V) (V^{\operatorname{T}} X^\prime)\\ -=& X^{\operatorname{T}} M_{\text{diag}} X \\ -=& \lambda_1 A^2+\lambda_2 Z^2\,. -\end{align}

- -
-
-
-
- -
- -
-
-

such that $|\lambda_1|\le|\lambda_2|$, where -\begin{align} -M_{\text{diag}}\equiv V^{\operatorname{T}} M V=\begin{bmatrix} -\lambda_1 & 0 \\ -0 & \lambda_2 \\ -\end{bmatrix}\,, -\end{align}

-

In this basis, the quadratic equation is in terms of eigenvalues and mixing angle, $\theta$. -Therefore, there are not longer mixed terms.

-

The diagonalization of quadratic equations can be straightforwardly generalized to $n$-th degree equations in terms of $n\times n$ matrices

- -
-
-
-
- -
- -
-
- -
-
-
import numpy as np
-g =0.64996
-gp=0.35523
-v=246.22046
-
- -
-
-
- -
-
- -
- -
-
-

Example: Electroweak interactions

To understand the electromagnetic and weak fundamental interactions, the mathematical formulation need to be done in one basis where the photon field, denoted with a symbol $A$, is still not well defined. Instead, the field $B$, the precursor of $A$, appears along with the weak field $W$, the precursor of the electroweak field $Z$. In the mathematical basis we have then -\begin{align} -X' = -\begin{bmatrix} -B \\ -W \\ -\end{bmatrix}, -\end{align} -and there, the symmetric mass matrix is calculated as (Details here: PDF)

- -
-
-
-
- -
- -
-
- -
-
-
-
- -
- -
-
- -
-
-
M=(v**2/4)*np.array([[gp**2,-g*gp],
-                     [-g*gp, g**2]])
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
M
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[ 1912.52692086, -3499.32718938],
-       [-3499.32718938,  6402.67629426]])
-
- -
-
-
-
- -
-
- -
- -
-
-

Checking that the determinant is zero

- -
-
-
-
- -
- -
-
- -
-
-
np.linalg.det(M).round(8)
-
- -
-
-
- -
-
- -
-
- - - -
-
0.0
-
- -
-
-
-
- -
-
- -
- -
-
-

This imply that one egivanlue is zero

- -
-
-
-
- -
- -
-
- -
-
-
np.linalg.eigvals(M).round(12)
-
- -
-
-
- -
-
- -
-
- - - -
-
array([   0.        , 8315.20321512])
-
- -
-
-
-
- -
-
- -
- -
-
-

which means that the matrix rank, the number of non-zero eigenvalues, is 1

- -
-
-
-
- -
- -
-
- -
-
-
np.linalg.matrix_rank(M)
-
- -
-
-
- -
-
- -
-
- - - -
-
1
-
- -
-
-
-
- -
-
- -
- -
-
-

To make the change to the phyisical basis, -$$ -X=\begin{bmatrix} -A\\ -Z -\end{bmatrix} -$$ -through the rotation matrix -$$ -V=\begin{bmatrix} -\cos\theta_W & \sin\theta_W\\ --\sin\theta_W & \cos\theta_W -\end{bmatrix}, -$$ -the following transformation need to be established -\begin{align} -X'= -\begin{bmatrix} -B\\ -W -\end{bmatrix}\equiv -\begin{bmatrix} -\cos\theta_W & \sin\theta_W\\ --\sin\theta_W & \cos\theta_W -\end{bmatrix} -\begin{bmatrix} -A\\ -Z -\end{bmatrix}= -V X\,, -\end{align} -such that $V$ is the diagonalization matrix of $M$

- -
-
-
-
- -
- -
-
-$$M_{\text{diag}}=V^{\operatorname{T}} M V$$

with the normal ordering: $|\lambda_1|\le|\lambda_2|$, and

- -
-
-
-
- -
- -
-
-
    -
  • $V$ → Diagonalization matrix
  • -
  • $V$ → Ortogonal matrix
  • -
  • $V$ → Rotation matrix
  • -
-

To obtain the eigensystem, we use

- -
-
-
-
- -
- -
-
- -
-
-
λ,V=np.linalg.eig(M)
-
- -
-
-
- -
-
- -
- -
-
-

which in fact satisfy

- -
-
-
-
- -
- -
-
- -
-
-
np.dot( np.dot(V.transpose(),M) , V).round(12)
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[  -0.        ,    0.        ],
-       [  -0.        , 8315.20321512]])
-
- -
-
-
-
- -
-
- -
- -
-
-

Since the first (zero) eigenvalue is the one associated to $A$, we can interpret directly the rotation matrix without changing the order of the eigenvectors

- -
-
-
-
- -
- -
-
- -
-
-
V
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[-0.87749437,  0.47958694],
-       [-0.47958694, -0.87749437]])
-
- -
-
-
-
- -
-
- -
- -
-
-

Note that in fact, the absolute value of the first element of the first eigenvector is the larger one and corresponds to the component along the $B$-axis.

- -
-
-
-
- -
- -
-
-

Therefore

- -
-
-
-
- -
- -
-
- -
-
-
θ_W=np.arcsin( V[0,1] )
-θ_W
-
- -
-
-
- -
-
- -
-
- - - -
-
0.5001839211647364
-
- -
-
-
-
- -
-
- -
- -
-
-

The eigenvalue associated to $Z$ is

- -
-
-
-
- -
- -
-
- -
-
-
mZ=np.sqrt(λ[1])
-mZ
-
- -
-
-
- -
-
- -
-
- - - -
-
91.18773610041056
-
- -
-
-
-
- -
-
- -
- -
-
-

corresponding to the $Z$ mass in units of $\text{GeV}/c^2$. As a reference, the proton mass is approximately $1\ \text{GeV}/c^2$

-

The physical observable associated to the weak mixing angle, $\theta_W$, is (see PDF, along with the $Z^0$ boson mass, $m_Z$)

- -
-
-
-
- -
- -
-
- -
-
-
np.sin(θ_W)**2
-
- -
-
-
- -
-
- -
-
- - - -
-
0.23000362966286086
-
- -
-
-
-
- -
-
- -
- -
-
-

Neutrino mass matrix

Returning back to the neutrino mixing discussion, it is worth noticing that in the mathematical basis -$$ -N=\left(\begin{array}{l} -\left|\nu_{e}\right\rangle \\ -\left|\nu_{\mu}\right\rangle \\ -\left|\nu_{\tau}\right\rangle -\end{array}\right) -$$ -the mass matrix, $\mathcal{M}_\nu$ is non-diagonal. However, if we assume that it is symmetric, then the previous rotation matrix there -$$ -\left(\begin{array}{l} -\left|\nu_{e}\right\rangle \\ -\left|\nu_{\mu}\right\rangle \\ -\left|\nu_{\tau}\right\rangle -\end{array}\right)= \boldsymbol{U}\left(\begin{array}{l} -\left|\nu_{1}\right\rangle \\ -\left|\nu_{2}\right\rangle \\ -\left|\nu_{3}\right\rangle -\end{array}\right), -$$ -corresponds to the diagonalization matrix -$$ -\boldsymbol{U}^\dagger \mathcal{M}_\nu \boldsymbol{U}=\operatorname{diag}(m_1,m_2,m_3). -$$

- -
-
-
-
- -
- -
-
-

Casas-Ibarra parameterization

Consider a $n\times n$ symmetric matrix $A$. We can assumme without lost of generality that this can be generated from a matrix $Y$ such that -$$ -A=Y^{\operatorname{T}}Y -$$ -Theorem 1 gurantees that exists an ortogonal matrix $U$ such that -$$ -U^{\operatorname{T}} A U=U^{\operatorname{T}} Y^{\operatorname{T}}Y U=D_\lambda -$$ -where -$$ -D_{\lambda}=A_{\text{diag}}=\operatorname{diag}\left(\lambda_1,\lambda_2,\ldots,\lambda_n\right) -$$ -where $\lambda_i$ are the eigenvalues of $A$. Therefore -\begin{align} - Y^{\operatorname{T}}Y =&U D_\lambda U^{\operatorname{T}}\\ - =&U D_{\sqrt{\lambda}} D_{\sqrt{\lambda}} U^{\operatorname{T}}\\ -\end{align} -where -$$ -D_{\sqrt{\lambda}}=\operatorname{diag}\left(\sqrt{\lambda_1},\sqrt{\lambda_2},\ldots \sqrt{\lambda_n}\right) -$$ -Therefore, exists an ortogonal arbitrary matrix $R$, such that -$$ - Y^{\operatorname{T}}Y =U D_{\sqrt{\lambda}}R^{\operatorname{T}}R D_{\sqrt{\lambda}} U^{\operatorname{T}}\\ -$$

-

In this way, the matrix $Y$ can be parameterized in terms of $R$ as -$$ -Y=R D_{\sqrt{\lambda}} U^{\operatorname{T}} -$$

-

1) By using the previous equations, build a $2\times 2$ $Y$ matrix with the following conditions

-
    -
  • $R$ is an orthogonal matrix with a rotation angle as a random number between $(0,2\pi)$. Use your identification number as the seed of the random number generator.
  • -
  • The eigenvalues are $\lambda_1=2$ and $\lambda_2=4$.
  • -
  • $U$ is a diagonalization matrix with mixing angle $\pi/4$
  • -
-

2) Build the matrix $A$ and check that has the proper eigenvalues and eigenvectors

- -
-
-
-
- -
- -
-
-

1)

- -
-
-
-
- -
- -
-
- -
-
-
import numpy as np
-
-np.random.seed(98554576)
-
-θ=np.random.uniform(0,2*np.pi)
-
-def orthogonal(θ):
-    return np.array( [[ np.cos(θ),  np.sin(θ)],
-                      [ -np.sin(θ), np.cos(θ) ]]    )
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
λ1=2; λ2=4
-R=orthogonal(θ)
-U=orthogonal(np.pi/4)
-D_sqrtλ=np.diag( np.sqrt([λ1,λ2]) )
-print('R=')
-R
-
- -
-
-
- -
-
- -
-
- -
-
R=
-
-
-
-
-
-
- - - -
-
array([[-0.81433017,  0.58040191],
-       [-0.58040191, -0.81433017]])
-
- -
-
-
-
- -
-
- -
- -
-
-

From the equation for $Y$

- -
-
-
-
- -
- -
-
- -
-
-
Y=np.dot( np.dot( R,D_sqrtλ), U.transpose() )
-
- -
-
-
- -
-
- -
- -
-
-

The symmetric matrix is

- -
-
-
-
- -
- -
-
- -
-
-
A=np.dot( Y.transpose(), Y)
-
- -
-
-
- -
-
- -
- -
-
-

2)

- -
-
-
-
- -
- -
-
- -
-
-
λ,Unew=np.linalg.eig(A)
-print('Eigenvalues={}'.format(λ))
-print('U=')
-Unew
-
- -
-
-
- -
-
- -
-
- -
-
Eigenvalues=[4. 2.]
-U=
-
-
-
-
-
-
- - - -
-
array([[ 0.70710678, -0.70710678],
-       [ 0.70710678,  0.70710678]])
-
- -
-
-
-
- -
-
- -
- -
-
-

After the reordering of the eigenvalues, we would obtain the original $U$ and therefore

- -
-
-
-
- -
- -
-
- -
-
-
np.dot( np.dot( U.transpose(),A ), U).round(15)
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[2., 0.],
-       [0., 4.]])
-
- -
-
-
-
- -
-
- -
- -
-
-

In this way, there is an infinity set of symmetric matrices $A$ which have the same eigenvalues and eigenvectors

- -
-
-
-
- -
- -
-
-

THDM CP-even masses and mixing

In this case we have the rotation between an interaction basis and a physical basis defined as -$$ -\begin{pmatrix} -R_1\\ -R_2\\ -\end{pmatrix}= -\begin{pmatrix} -\cos\alpha & -\sin\alpha \\ -\sin\alpha & \cos\alpha \\ -\end{pmatrix} -\begin{pmatrix} -H\\ -h\\ -\end{pmatrix}. -$$ -Since the diagonalization of a symmetric $2\times 2$ matrix can be obtained analitically, -here we build a $2\times 2$ symmetric matrix from the eigenvalues, $m_H$ and $m_h$, and the rotation angle, $\alpha$, and check with the numerical results by using a benchmark point:

-

Benchmark point BP9

- -
-
-
-
- -
- -
-
- -
-
-
import numpy as np
-from scipy import optimize
-G_F=1.1663787E-5 #GeV^-2
-v=1/np.sqrt(np.sqrt(2.)*G_F) # GeV
-
-#*********  BP9 ************
-tanβ=2
-sinβ_α=0.6   # sin(β-α)
-m_h = 125    # GeV/c^2 (c→1)
-m_H = 300    # GeV/c^2 
-m_A = 300    # GeV/c^2
-m_Hp= 400    # GeV/c^2
-m2_12=100**2 # (GeV/c^2)^2
-#***********************
-
- -
-
-
- -
-
- -
- -
-
-

The formula for the mass matrix in terms of the previous parameters can be found in [hep-ph/0207010,arXiv:1507.00933]. We assumme here that $\lambda_6=\lambda_7=0$. See Appendix D of [hep-ph/0207010] for full formulas

- -
-
-
-
- -
- -
-
- -
-
-
β=np.arctan(tanβ)
-α=β-np.arcsin(sinβ_α) # <= np.pi/2~1.57
-print('α=',α)
-λ1  =(m_H**2*np.cos(α)**2+m_h**2*np.sin(α)**2-m2_12*np.tan(β))/(v**2*np.cos(β)**2)
-λ_2 =(m_H**2*np.sin(α)**2+m_h**2*np.cos(α)**2-m2_12/np.tan(β))/(v**2*np.sin(β)**2)
-λ3  =((m_H**2-m_h**2)*np.cos(α)*np.sin(α)+2*m_Hp**2*np.sin(β)*np.cos(β)-m2_12)/(v**2*np.sin(β)*np.cos(β))
-λ4  =((m_A**2-2*m_Hp**2)*np.sin(β)*np.cos(β)+m2_12)/(v**2*np.sin(β)*np.cos(β))
-λ5  =(m2_12-m_A**2*np.sin(β)*np.cos(β))/(v**2*np.sin(β)*np.cos(β))
-λ345=λ3+λ4+λ5
-λ345
-
- -
-
-
- -
-
- -
-
- -
-
α= 0.46364760900080604
-
-
-
-
-
-
- - - -
-
1.63919914780058
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
def M2(β,λ1,λ_2,λ5,λ345,m2_12,v=246.2):
-    mA2=m2_12/(np.sin(β)*np.cos(β))-λ5*v**2
-    M11=λ1*v**2*np.cos(β)**2+(mA2+λ5*v**2)*np.sin(β)**2
-    M12=(λ345*v**2-(mA2+λ5*v**2))*np.sin(β)*np.cos(β)
-    M22=λ_2*v**2*np.sin(β)**2+(mA2+λ5*v**2)*np.cos(β)**2
-    return np.array( [[M11, M12],
-                      [M12, M22]])
-
- -
-
-
- -
-
- -
- -
-
-

In this way, from the BP point, we can build the $2\times2$ symmetric mass $\mathcal{M}$:

- -
-
-
-
- -
- -
-
- -
-
-
ℳ2=M2(β,λ1,λ_2,λ5,λ345,m2_12,v=v)
-ℳ2
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[75125., 29750.],
-       [29750., 30500.]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
m2,V=np.linalg.eig(ℳ2)
-
- -
-
-
- -
-
- -
- -
-
-

By using the proper basis -$$ -\left(\begin{array}{cc} -m_{H}^{2} & 0 \\ -0 & m_{h}^{2} -\end{array}\right)=\left(\begin{array}{rr} -\cos{\alpha} & \sin{\alpha} \\ --\sin{\alpha} & \cos{\alpha} -\end{array}\right)\left(\begin{array}{ll} -\mathcal{M}_{11}^{2} & \mathcal{M}_{12}^{2} \\ -\mathcal{M}_{12}^{2} & \mathcal{M}_{22}^{2} -\end{array}\right)\left(\begin{array}{lr} -\cos{\alpha} & -\sin{\alpha} \\ -\sin{\alpha} & \cos{\alpha} -\end{array}\right). -$$ -Therefore -$$ -U=\left(\begin{array}{lr} -\cos{\alpha} & -\sin{\alpha} \\ -\sin{\alpha} & \cos{\alpha} -\end{array}\right). -$$ -Since $-\pi/2\le\alpha\le\pi/2$ then $\cos\alpha\ge 0$. In this way, we must obtain $\alpha$ from $\tan\alpha$ to avoid ambiguities with a global sign in the second eigenvector -$$ -\tan\alpha=\frac{\sin\alpha}{\cos\alpha}=-\frac{U_{01}}{U_{11}}\,. -$$

-

The eigenvector with large projection in the second component along $R_2$ ( Interaction basis $(R_1,R_2)$ → Mass basis $(H^0,h^0)$) is the associated with the standard model Higgs mass, $m_h$

- -
-
-
-
- -
- -
-
- -
-
-
if np.abs(V[0,1])<=np.abs(V[1,1]):
-    H=0; h=1
-else:
-    H=1; h=0
-(H,h)
-
- -
-
-
- -
-
- -
-
- - - -
-
(0, 1)
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
U=np.c_[ V[:,H],V[:,h]  ]
-U
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[ 0.89442719, -0.4472136 ],
-       [ 0.4472136 ,  0.89442719]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
M2diag=np.dot( np.dot( U.transpose(),ℳ2), U).round(9)
-mH,mh=np.sqrt(M2diag[0,0]),np.sqrt(M2diag[1,1])
-mH,mh
-
- -
-
-
- -
-
- -
-
- - - -
-
(300.0, 125.0)
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
tanα=-U[0,1]/U[1,1]
-
-α=np.arctan(tanα)
-if α>=-np.pi/2 and α<=np.pi/2:
-    print(α)
-else:
-    print('Bad α range')
-
- -
-
-
- -
-
- -
-
- -
-
0.4636476090008061
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
np.cos(β-α)
-
- -
-
-
- -
-
- -
-
- - - -
-
0.8
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
np.sin(β-α)
-
- -
-
-
- -
-
- -
-
- - - -
-
0.5999999999999999
-
- -
-
-
-
- -
-
- -
- -
-
-

Analytical diagonalization from [arXiv:1507.00933]

- -
-
-
-
- -
- -
-
- -
-
-
Δ=np.sqrt(  (ℳ2[0,0]-ℳ2[1,1])**2+4*ℳ2[0,1]**2 )
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
np.sqrt( [0.5*( ℳ2[0,0]+ℳ2[1,1]+Δ ),
-          0.5*( ℳ2[0,0]+ℳ2[1,1]-Δ ) ])
-
- -
-
-
- -
-
- -
-
- - - -
-
array([300., 125.])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
Cosα,Sinα=( np.sqrt((Δ+ℳ2[0,0]-ℳ2[1,1])/(2*Δ)),
-            np.sqrt(2)*ℳ2[0,1]/np.sqrt(Δ*(Δ+ℳ2[0,0]-ℳ2[1,1])) )
-print('U=')
-np.array([[Cosα,-Sinα],[Sinα,Cosα]])
-
- -
-
-
- -
-
- -
-
- -
-
U=
-
-
-
-
-
-
- - - -
-
array([[ 0.89442719, -0.4472136 ],
-       [ 0.4472136 ,  0.89442719]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
print('cos(β-α)={}'.format(np.cos( β- np.arctan( Sinα/Cosα) )))
-
- -
-
-
- -
-
- -
-
- -
-
cos(β-α)=0.8
-
-
-
-
-
-
- -
-
- - - - -
- \ No newline at end of file diff --git a/_build/features/linear-algebra-extra.html b/_build/features/linear-algebra-extra.html deleted file mode 100644 index 23e2f64..0000000 --- a/_build/features/linear-algebra-extra.html +++ /dev/null @@ -1,195 +0,0 @@ ---- -interact_link: content/features/linear-algebra-extra.ipynb -kernel_name: python3 -kernel_path: content/features -has_widgets: false -title: |- - Custum Gaussian elimination -pagenum: 22 -prev_page: - url: /features/linear-algebra-diagonalization.html -next_page: - url: /features/differential-equations.html -suffix: .ipynb -search: extra material linear algebra custom implementation general gaussian method - -comment: "***PROGRAMMATICALLY GENERATED, DO NOT EDIT. SEE ORIGINAL FILES IN /content***" ---- - -
-
Custum Gaussian elimination
-
-
- -
-
-

Extra material about Linear Algebra

-
-
-
-
- -
- -
-
- -
-
-
import numpy as np
-xrange=range
-
- -
-
-
- -
-
- -
- -
-
-

Custom implementation of general gaussian method

-
-
-
-
- -
- -
-
- -
-
-
#Gaussian Elimination
-def row_lamb( i, lamb, A ):
-    B = np.copy(A)
-    B[i] = lamb*B[i]
-    return B
-
-#Combination function
-def row_comb( i, j, lamb, A ):
-    B = np.copy(A)
-    B[i] = lamb*B[j] + B[i]
-    return B
-
-#Swap function
-def row_swap( i, j, A ):
-    B = np.copy(A)
-    B[[i,j]] = B[[j,i]]
-    return B
-
-def Gaussian_Elimination( A0 ):
-    #Making local copy of matrix
-    A = np.copy(A0)
-    #Detecting size of matrix
-    n = len(A)
-    
-    #Sweeping all the columns in order to eliminate coefficients of the i-th variable
-    for i in xrange( 0, n ):
-        
-        #Sweeping all the rows for the i-th column in order to find the first non-zero coefficient
-        for j in xrange( i, n ):
-            if A[i,j] != 0:
-                #Normalization coefficient
-                Norm = 1.0*A[i,j]
-                break
-                
-        #Applying swap operation to put the non-zero coefficient in the i-th row
-        A = row_swap( i, j, A )
-        
-        #Eliminating the coefficient associated to the i-th variable
-        for j in xrange( i+1, n ):
-            A = row_comb( j, i, -A[j,i]/Norm, A )
-            
-    #Normalizing n-th variable
-    A = row_lamb( n-1, 1.0/A[n-1,n-1], A )
-    
-    #Finding solution
-    x = np.zeros( n )
-    x[n-1] = A[n-1,n]
-    for i in xrange( n-1, -1, -1 ):
-        x[i] = ( A[i,n] - sum(A[i,i+1:n]*x[i+1:n]) )/A[i,i]
-    
-    #Upper diagonal matrix and solutions x
-    return A, x
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
np.random.seed(3)
-M =  np.random.random( (4,5) )
-print ("Augmented Matrix M:\n", M, "\n")
-#Solving using Gaussian Elimination
-D, x = Gaussian_Elimination(M)
-print ("Augmented Diagonal Matrix D:\n", D, "\n")
-print ("Obtained solution:\n", x, "\n")
-print ("Exact solution:\n", (M[:,:4]**-1*M[:,4]).T, "\n")
-
- -
-
-
- -
-
- -
-
- -
-
Augmented Matrix M:
- [[0.5507979  0.70814782 0.29090474 0.51082761 0.89294695]
- [0.89629309 0.12558531 0.20724288 0.0514672  0.44080984]
- [0.02987621 0.45683322 0.64914405 0.27848728 0.6762549 ]
- [0.59086282 0.02398188 0.55885409 0.25925245 0.4151012 ]] 
-
-Augmented Diagonal Matrix D:
- [[ 5.50797903e-01  7.08147823e-01  2.90904739e-01  5.10827605e-01
-   8.92946954e-01]
- [ 0.00000000e+00 -1.02675749e+00 -2.66135662e-01 -7.79783697e-01
-  -1.01224976e+00]
- [ 0.00000000e+00  0.00000000e+00  5.24909828e-01 -6.69967089e-02
-   2.15310020e-01]
- [ 0.00000000e+00  0.00000000e+00 -1.70372042e-16  1.00000000e+00
-   9.32073626e-03]] 
-
-Obtained solution:
- [0.27395594 0.8721633  0.41137442 0.00932074] 
-
-Exact solution:
- [[ 1.62118801  0.9962667  29.88822639  1.51125934]
- [ 0.62248281  3.51004303  0.9649251  18.38095262]
- [ 2.324661    3.26310322  1.041764    1.21007418]
- [ 0.81260526  8.06535367  1.4905571   1.60114669]] 
-
-
-
-
-
-
-
- -
-
- - - - -
- \ No newline at end of file diff --git a/_build/features/linear-algebra.html b/_build/features/linear-algebra.html deleted file mode 100644 index 95c3b0c..0000000 --- a/_build/features/linear-algebra.html +++ /dev/null @@ -1,5069 +0,0 @@ ---- -interact_link: content/features/linear-algebra.ipynb -kernel_name: python3 -kernel_path: content/features -has_widgets: false -title: |- - Linear algebra -pagenum: 20 -prev_page: - url: /features/numerical-calculus-integration-methods.html -next_page: - url: /features/linear-algebra-diagonalization.html -suffix: .ipynb -search: n matrix vdots mathbf b cdots x m left right e computing j ij frac l times linear ei matrices det hat gaussian span equations elimination system operations determinant using r k operation determinants factorization example previous inverse mbox systems row order ej boldsymbol where lu rows lambda given equation nn diagonal algebra general array arrays next activity u numpy both style color red solve align coefficients upper necessary algorithm method operatorname associated obtain xn y colab not large errors pivoting also column begin end leq routine psi com vector python properties integer possible set new function return ib problem - -comment: "***PROGRAMMATICALLY GENERATED, DO NOT EDIT. SEE ORIGINAL FILES IN /content***" ---- - -
-
Linear algebra
-
-
- -
-
-

Open In Colab

- -
-
-
-
- -
- -
-
-

Linear Algebra

Open In Colab

- -
-
-
-
- -
- -
-
-

Linear Algebra is a discipline where vector spaces and linear mapping between them are studied. In physics and astronomy, several phenomena can be readily written in terms of linear variables, what makes Computational Linear Algebra a very important topic to be covered throughout this course. We shall cover linear systems of equations, techniques for calculating inverses and determinants and factorization methods.

-

An interesting fact of Computational Linear Algebra is that it does not comprises numerical approaches as most of the methods are exact. The usage of a computer is then necessary because of the large number of calculations rather than the non-soluble nature of the problems. Numerical errors come then from round-off approximations.

-

See: http://pages.cs.wisc.edu/~amos/412/lecture-notes/lecture14.pdf

- -
-
-
-
- - - -
- -
-
- -
-
-
from IPython.display import HTML, Markdown, YouTubeVideo,Latex
-%pylab inline
-
-import numpy as np
-import matplotlib.pyplot as plt
-# JSAnimation import available at https://github.com/jakevdp/JSAnimation
-#from JSAnimation import IPython_display
-from matplotlib import animation
-#Interpolation add-on
-import scipy.interpolate as interp
-xrange=range
-
- -
-
-
- -
-
- -
-
- -
-
Populating the interactive namespace from numpy and matplotlib
-
-
-
-
-
-
- -
-
- - - -
- -
-
- -
-
-
try:
-    from google.colab.output._publish import javascript
-    from IPython.display import Math as math
-    from IPython.display import Latex as latex
-    url = "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/latest.js?config=default"
-    def Math(*args,**kwargs):
-        javascript(url=url)
-        return math(*args,**kwargs)
-    def Latex(*args,**kwargs):
-        #print(args[0].replace('$',''))
-        javascript(url=url)
-        return math(args[0],**kwargs)
-except:
-    from IPython.display import Math, Latex
-
- -
-
-
- -
-
- -
-
- -
-
/usr/local/lib/python3.7/dist-packages/IPython/utils/traitlets.py:5: UserWarning: IPython.utils.traitlets has moved to a top-level traitlets package.
-  warn("IPython.utils.traitlets has moved to a top-level traitlets package.")
-
-
-
-
-
-
- -
-
- -
- -
-
-
- -
-
-
-
- -
- -
-
-

Matrices in Python

-
-
-
-
- -
- -
-
-

One of the most useful advantages of high level languages like Python, is the manipulation of complex objects like matrices and vectors. For this part we are going to use advanced capabilities for handling matrices, provided by the library NumPy.

-

NumPy, besides the extreme useful NumPy array objects, also provides the Matrix objects that are overloaded with proper matrix operations.

-

Numpy arrays

    -
  • A matrix can be represented by an array of two indices
  • -
- -
-
-
-
- -
- -
-
- -
-
-
#NumPy Arrays
-M1 = np.array( [[ 5 ,-4, 0],
-                [-4 , 7,-3],
-                [ 0 ,-3, 5]] )
-M2 = np.array( [[3,-2,1],[-1,5,4],[1,-2,3]] )
-print( 'M1=\n{}, with shape={},\n\nM2=\n{}'.format(M1,M1.shape,M2) )
-
- -
-
-
- -
-
- -
-
- -
-
M1=
-[[ 5 -4  0]
- [-4  7 -3]
- [ 0 -3  5]], with shape=(3, 3),
-
-M2=
-[[ 3 -2  1]
- [-1  5  4]
- [ 1 -2  3]]
-
-
-
-
-
-
- -
-
- -
- -
-
-

Note tha the previous definitions correspond to integer arrays.

-

WARNING: Be careful with integer arrays. In the next example, a single float entry convert the full matrix from an integer array to a float array:

- -
-
-
-
- -
- -
-
- -
-
-
M1[0,0]
-
- -
-
-
- -
-
- -
-
- - - -
-
5
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
np.array([[ 5, -4,  0],
-          [-4,  7, -3.],
-          [ 0, -3,  5]])[0,0]
-
- -
-
-
- -
-
- -
-
- - - -
-
5.0
-
- -
-
-
-
- -
-
- -
- -
-
-

Special arrays:

Let $n$ the range of the matrix

-
    -
  • zero matrix
  • -
- -
-
-
-
- -
- -
-
- -
-
-
n=3
-np.zeros( (n,n) )
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[0., 0., 0.],
-       [0., 0., 0.],
-       [0., 0., 0.]])
-
- -
-
-
-
- -
-
- -
- -
-
-
    -
  • Ones matrix
  • -
- -
-
-
-
- -
- -
-
- -
-
-
np.ones( (n,n) )
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[1., 1., 1.],
-       [1., 1., 1.],
-       [1., 1., 1.]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
np.ones( (n,n) )*1j
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[0.+1.j, 0.+1.j, 0.+1.j],
-       [0.+1.j, 0.+1.j, 0.+1.j],
-       [0.+1.j, 0.+1.j, 0.+1.j]])
-
- -
-
-
-
- -
-
- -
- -
-
-
    -
  • Identity matrix
  • -
- -
-
-
-
- -
- -
-
- -
-
-
np.identity(n)
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[1., 0., 0.],
-       [0., 1., 0.],
-       [0., 0., 1.]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
np.diag([1,2,4])
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[1, 0, 0],
-       [0, 2, 0],
-       [0, 0, 4]])
-
- -
-
-
-
- -
-
- -
- -
-
-
    -
  • Random matrix with entries between 0 and 1
  • -
- -
-
-
-
- -
- -
-
- -
-
-
np.random.random((n,n))
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[0.03759466, 0.03529442, 0.77509671],
-       [0.65252241, 0.71648007, 0.09995053],
-       [0.11837179, 0.08144293, 0.62915985]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
np.random.uniform(0,10,(n,n))
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[0.69568594, 5.55397727, 2.52884654],
-       [0.92956248, 7.03556212, 7.69677769],
-       [3.17346739, 1.12515801, 2.84483672]])
-
- -
-
-
-
- -
-
- -
- -
-
-
    -
  • Integer Random matrix
  • -
- -
-
-
-
- -
- -
-
- -
-
-
np.random.randint(0,10,(n,n)) #0 to 9
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[9, 0, 5],
-       [4, 5, 7],
-       [0, 0, 6]])
-
- -
-
-
-
- -
-
- -
- -
-
-

Analytical matrices

Some times it is necessary to work with analytical Matrices. In such a case we can use the symbolic module Sympy

- -
-
-
-
- -
- -
-
- -
-
-
import sympy
-x =sympy.Symbol('x') # declare analytical varibles
-sympy.init_printing() # Use LaTeX to print sympy obejects
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
sympy.Matrix(M2)
-
- -
-
-
- -
-
- -
-
- - - -
-$\displaystyle \left[\begin{matrix}3 & -2 & 1\\-1 & 5 & 4\\1 & -2 & 3\end{matrix}\right]$ -
- -
-
-
-
- -
-
- -
- -
-
-

In the following we will focus only in numerical matrices as numpy arrays, but also use sympy to print the matrices in a more readable way

-

Matrix operations (numpy)

Both as functions or array's methods

-
    -
  • Transpose
  • -
- -
-
-
-
- -
- -
-
- -
-
-
display( Math(r'M_2^{\rm T}='))
-sympy.Matrix( M2.transpose())
-
- -
-
-
- -
-
- -
-
- - -
- -
- -
-
-
-
- - - -
-$$M_2^{\rm T}=$$ -
- -
-
-
-
- - - -
-$\displaystyle \left[\begin{matrix}3 & -1 & 1\\-2 & 5 & -2\\1 & 4 & 3\end{matrix}\right]$ -
- -
-
-
-
- -
-
- -
- -
-
-
    -
  • Matrix addition
  • -
- -
-
-
-
- -
- -
-
- -
-
-
sympy.Matrix( M1+M2 )
-
- -
-
-
- -
-
- -
-
- - - -
-$\displaystyle \left[\begin{matrix}8 & -6 & 1\\-5 & 12 & 1\\1 & -5 & 8\end{matrix}\right]$ -
- -
-
-
-
- -
-
- -
- -
-
-

Complex arrays are allowed

- -
-
-
-
- -
- -
-
- -
-
-
Mc=M1+M2*1j
-sympy.Matrix( M1+M2*1j )
-
- -
-
-
- -
-
- -
-
- - - -
-$\displaystyle \left[\begin{matrix}5.0 + 3.0 i & -4.0 - 2.0 i & 1.0 i\\-4.0 - 1.0 i & 7.0 + 5.0 i & -3.0 + 4.0 i\\1.0 i & -3.0 - 2.0 i & 5.0 + 3.0 i\end{matrix}\right]$ -
- -
-
-
-
- -
-
- -
- -
-
-

with the corresponding complex matrix operations

- -
-
-
-
- -
- -
-
- -
-
-
display ( sympy.Matrix(  Mc.conjugate() ) )
-display ( sympy.Matrix(  Mc.conjugate().transpose() ) ) # hermítico-conjugado
-
- -
-
-
- -
-
- -
-
- - - -
-$\displaystyle \left[\begin{matrix}5.0 - 3.0 i & -4.0 + 2.0 i & - 1.0 i\\-4.0 + 1.0 i & 7.0 - 5.0 i & -3.0 - 4.0 i\\- 1.0 i & -3.0 + 2.0 i & 5.0 - 3.0 i\end{matrix}\right]$ -
- -
-
-
-
- - - -
-$\displaystyle \left[\begin{matrix}5.0 - 3.0 i & -4.0 + 1.0 i & - 1.0 i\\-4.0 + 2.0 i & 7.0 - 5.0 i & -3.0 + 2.0 i\\- 1.0 i & -3.0 - 4.0 i & 5.0 - 3.0 i\end{matrix}\right]$ -
- -
-
-
-
- -
-
- -
- -
-
-
    -
  • Matrix multiplication -MP
  • -
- -
-
-
-
- -
- -
-
-
dot(a, b, out=None)
-
-

Dot product of two arrays. Specifically,

-
    -
  • If both a and b are 1-D arrays, it is inner product of vectors -(without complex conjugation).

    -
  • -
  • If both a and b are 2-D arrays, it is matrix multiplication, -but using :func:matmul or a @ b is preferred.

    -
  • -
  • If either a or b is 0-D (scalar), it is equivalent to :func:multiply -and using numpy.multiply(a, b) or a * b is preferred.

    -
  • -
  • ...

    -
  • -
- -
-
-
-
- -
- -
-
- -
-
-
#Multiplication
-sympy.Matrix ( np.dot( M1, M2 ) )
-
- -
-
-
- -
-
- -
-
- - - -
-$\displaystyle \left[\begin{matrix}19 & -30 & -11\\-22 & 49 & 15\\8 & -25 & 3\end{matrix}\right]$ -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#Multiplication is not commutative
-sympy.Matrix ( np.dot( M2, M1 ) )
-
- -
-
-
- -
-
- -
-
- - - -
-$\displaystyle \left[\begin{matrix}23 & -29 & 11\\-25 & 27 & 5\\13 & -27 & 21\end{matrix}\right]$ -
- -
-
-
-
- -
-
- -
- -
-
-
    -
  • Complex matrices
  • -
- -
-
-
-
- -
- -
-
- -
-
-
σ_2=np.array([[0,-1j],[1j,0]])
-sympy.Matrix(σ_2)
-
- -
-
-
- -
-
- -
-
- - - -
-$\displaystyle \left[\begin{matrix}0 & - 1.0 i\\1.0 i & 0\end{matrix}\right]$ -
- -
-
-
-
- -
-
- -
- -
-
-
    -
  • Trace
  • -
- -
-
-
-
- -
- -
-
- -
-
-
np.trace(σ_2)
-
- -
-
-
- -
-
- -
-
- - - -
-
0j
-
- -
-
-
-
- -
-
- -
- -
-
-
    -
  • Determinant
  • -
- -
-
-
-
- -
- -
-
- -
-
-
np.linalg.det(σ_2)
-
- -
-
-
- -
-
- -
-
- - - -
-
(-1+0j)
-
- -
-
-
-
- -
-
- -
- -
-
-

Raise a square matrix to the (integer) power n.

- -
-
-
-
- -
- -
-
- -
-
-
sympy.Matrix ( np.linalg.matrix_power(σ_2,2) )
-
- -
-
-
- -
-
- -
-
- - - -
-$\displaystyle \left[\begin{matrix}1.0 & 0\\0 & 1.0\end{matrix}\right]$ -
- -
-
-
-
- -
-
- -
- -
-
-

odd power

- -
-
-
-
- -
- -
-
- -
-
-
sympy.Matrix ( np.linalg.matrix_power(σ_2,7) )
-
- -
-
-
- -
-
- -
-
- - - -
-$\displaystyle \left[\begin{matrix}0 & - 1.0 i\\1.0 i & 0\end{matrix}\right]$ -
- -
-
-
-
- -
-
- -
- -
-
-

even power

- -
-
-
-
- -
- -
-
- -
-
-
sympy.Matrix ( np.linalg.matrix_power(σ_2,14) )
-
- -
-
-
- -
-
- -
-
- - - -
-$\displaystyle \left[\begin{matrix}1.0 & 0\\0 & 1.0\end{matrix}\right]$ -
- -
-
-
-
- -
-
- -
- -
-
-

Inverse of a matrix

- -
-
-
-
- -
- -
-
- -
-
-
sympy.Matrix( np.linalg.inv(M2) )
-
- -
-
-
- -
-
- -
-
- - - -
-$\displaystyle \left[\begin{matrix}0.442307692307692 & 0.0769230769230769 & -0.25\\0.134615384615385 & 0.153846153846154 & -0.25\\-0.0576923076923077 & 0.0769230769230769 & 0.25\end{matrix}\right]$ -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
sympy.Matrix ( np.dot( M2,np.linalg.inv(M2) ).round(15).astype(int) )
-
- -
-
-
- -
-
- -
-
- - - -
-$\displaystyle \left[\begin{matrix}1 & 0 & 0\\0 & 1 & 0\\0 & 0 & 1\end{matrix}\right]$ -
- -
-
-
-
- -
-
- -
- -
-
-

Element by element operations

-
-
-
-
- -
- -
-
- -
-
-
print(M1)
-M2
-
- -
-
-
- -
-
- -
-
- -
-
[[ 5 -4  0]
- [-4  7 -3]
- [ 0 -3  5]]
-
-
-
-
-
-
- - - -
-
array([[ 3, -2,  1],
-       [-1,  5,  4],
-       [ 1, -2,  3]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
M1*M2
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[ 15,   8,   0],
-       [  4,  35, -12],
-       [  0,   6,  15]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#Division
-print( M1/M2 )
-
- -
-
-
- -
-
- -
-
- -
-
[[ 1.66666667  2.          0.        ]
- [ 4.          1.4        -0.75      ]
- [ 0.          1.5         1.66666667]]
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
sympy.Matrix( np.dot(M1,np.linalg.inv(M2)).round(3) )
-
- -
-
-
- -
-
- -
-
- - - -
-$\displaystyle \left[\begin{matrix}1.673 & -0.231 & -0.25\\-0.654 & 0.538 & -1.5\\-0.692 & -0.077 & 2.0\end{matrix}\right]$ -
- -
-
-
-
- -
-
- -
- -
-
-

Submatrix from matrix:

-
-
-
-
- -
- -
-
- -
-
-
M1 = np.array( [[ 5 ,-4, 0],
-                [-4 , 7,-3],
-                [ 0 ,-3, 5]] )
-
- -
-
-
- -
-
- -
- -
-
-

Elements of the matrix

- -
-
-
-
- -
- -
-
- -
-
-
M1[1,2]
-
- -
-
-
- -
-
- -
-
- - - -
-
-3
-
- -
-
-
-
- -
-
- -
- -
-
-

Extract rows

-
-
-
-
- -
- -
-
- -
-
-
M1[1,:]
-
- -
-
-
- -
-
- -
-
- - - -
-
array([-4,  7, -3])
-
- -
-
-
-
- -
-
- -
- -
-
-

or

- -
-
-
-
- -
- -
-
- -
-
-
M1[1]
-
- -
-
-
- -
-
- -
-
- - - -
-
array([-4,  7, -3])
-
- -
-
-
-
- -
-
- -
- -
-
-

In general: -M1[list of rows to extract]

- -
-
-
-
- -
- -
-
- -
-
-
M1[[1]]
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[-4.,  7., -3.]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
M1[[0,2]]
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[0. , 0. , 0.3],
-       [0.3, 0. , 0. ]])
-
- -
-
-
-
- -
-
- -
- -
-
-

Extract columns

-
-
-
-
- -
- -
-
- -
-
-
M1[:,1]
-
- -
-
-
- -
-
- -
-
- - - -
-
array([-4,  7, -3])
-
- -
-
-
-
- -
-
- -
- -
-
-

and convert back into a column

- -
-
-
-
- -
- -
-
- -
-
-
np.c_[M1[:,1]]
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[-4],
-       [ 7],
-       [-3]])
-
- -
-
-
-
- -
-
- -
- -
-
-

Reordering

-
-
-
-
- -
- -
-
-

Reverse row order to 2,1,0

- -
-
-
-
- -
- -
-
- -
-
-
M1[[2,1,0]]
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[ 0, -3,  5],
-       [-4,  7, -3],
-       [ 5, -4,  0]])
-
- -
-
-
-
- -
-
- -
- -
-
-

or

- -
-
-
-
- -
- -
-
- -
-
-
np.r_[[M1[2]],[M1[1]],[M1[0]]]
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[ 0, -3,  5],
-       [-4,  7, -3],
-       [ 5, -4,  0]])
-
- -
-
-
-
- -
-
- -
- -
-
-

Reverse column order to 2,1,0

- -
-
-
-
- -
- -
-
- -
-
-
np.c_[ M1[:,2],M1[:,1],M1[:,0]  ]
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[ 0, -4,  5],
-       [-3,  7, -4],
-       [ 5, -3,  0]])
-
- -
-
-
-
- -
-
- -
- -
-
-

It is possible to reasign a full set of rows to a matrix

-
-
-
-
- -
- -
-
- -
-
-
M1 = np.array( [[ 5,-4, 0],
-                [-4, 7,-3],
-                [ 0,-3, 5]] )
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
M1[[0,2]]=[[0  ,0,0.3],
-           [0.3,0,0  ]]
-M1
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[ 0,  0,  0],
-       [-4,  7, -3],
-       [ 0,  0,  0]])
-
- -
-
-
-
- -
-
- -
- -
-
-

Note that because M1 has only integer numbers, it is assumed to be an integer matrix. In order to allow float assignments, it is first necessary to convert to a float matrix:

- -
-
-
-
- -
- -
-
- -
-
-
M1=M1.astype(float)
-M1[[0,2]]=[[0  ,0,0.3],
-           [0.3,0,0  ]]
-M1
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[ 0. ,  0. ,  0.3],
-       [-4. ,  7. , -3. ],
-       [ 0.3,  0. ,  0. ]])
-
- -
-
-
-
- -
-
- -
- -
-
-

WARNING
-In some cases a reasignment of a list or array points to the same space in memory. To really copy an array to other variable it is always recommended to use the .copy() method.

- -
-
-
-
- -
- -
-
- -
-
-
A=np.array([1,2])
-A
-
- -
-
-
- -
-
- -
-
- - - -
-
array([1, 2])
-
- -
-
-
-
- -
-
- -
- -
-
-

Reassign memory space

- -
-
-
-
- -
- -
-
- -
-
-
C=A
-C
-
- -
-
-
- -
-
- -
-
- - - -
-
array([1, 2])
-
- -
-
-
-
- -
-
- -
- -
-
-

A change is reflected in both variables

- -
-
-
-
- -
- -
-
- -
-
-
C[0]=5
-print('A={} → C={}'.format(A,C))
-
- -
-
-
- -
-
- -
-
- -
-
A=[5 2] → C=[5 2]
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
A[1]=8
-print('A={} → C={}'.format(A,C))
-
- -
-
-
- -
-
- -
-
- -
-
A=[5 8] → C=[5 8]
-
-
-
-
-
-
- -
-
- -
- -
-
-

To keep the first memory space

- -
-
-
-
- -
- -
-
- -
-
-
B=A.copy() # two different memory spaces
-B[0]=4
-print('A =',A)
-print('B =',B)
-
- -
-
-
- -
-
- -
-
- -
-
A = [5 8]
-B = [4 8]
-
-
-
-
-
-
- -
-
- -
- -
-
-

Matrix object

-
-
-
-
- -
- -
-
-

numpy also has a Matrix object with simplified operations. However it is recommended to use the general array object even for specific matrix operations. This helps to avoid incompatibilities with usual array operations. For example, as shown below the multiplication symbol, *, behaves different for arrays that for matrices, and could induce to errors.

- -
-
-
-
- -
- -
-
- -
-
-
#NumPy Matrix
-M1 = np.matrix( [[5,-4,0],[-4,7,-3],[0,-3,5]] )
-M2 = np.matrix( [[3,-2,1],[-1,5,4],[1,-2,3]] )
-
-print (M1, "\n")
-print (M2)
-
- -
-
-
- -
-
- -
-
- -
-
[[ 5 -4  0]
- [-4  7 -3]
- [ 0 -3  5]] 
-
-[[ 3 -2  1]
- [-1  5  4]
- [ 1 -2  3]]
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
#Addition
-sympy.Matrix( M1+M2 )
-
- -
-
-
- -
-
- -
-
- - - -
-$\displaystyle \left[\begin{matrix}8 & -6 & 1\\-5 & 12 & 1\\1 & -5 & 8\end{matrix}\right]$ -
- -
-
-
-
- -
-
- -
- -
-
-

MP

- -
-
-
-
- -
- -
-
- -
-
-
#Multiplication
-sympy.Matrix( M1*M2 )
-
- -
-
-
- -
-
- -
-
- - - -
-$\displaystyle \left[\begin{matrix}19 & -30 & -11\\-22 & 49 & 15\\8 & -25 & 3\end{matrix}\right]$ -
- -
-
-
-
- -
-
- -
- -
-
-

Basic operations with matrices

-
-
-
-
- -
- -
-
-

In order to simplify the following methods, we introduce here 3 basic operations over linear systems:

-
    -
  1. The $i$-th row $E_i$ can be multiplied by a non-zero constant $\lambda$, and then a new row used in place of $E_i$, i.e. $(E_i)\rightarrow (\lambda E_i)$. We denote this operation as $\operatorname{Lamb}(E_i,\lambda)$.
  2. -
  3. The $j$-th row $E_j$ can be multiplied by a non-zero constant $\lambda$ and added to some row $E_i$. The resulting value take the place of $E_i$, i.e. $(E_i) \rightarrow (E_i + \lambda E_j)$. We denote this operation as $\operatorname{Comb}(E_i,E_j,\lambda)$.
  4. -
  5. Finally, we define a swapping of two rows as $(E_i)\leftrightarrow (E_j)$, denoted as $\operatorname{Swap}(E_i,E_j)$
  6. -
- -
-
-
-
- -
- -
-
-

Extract rows from an array

-
-
-
-
- -
- -
-
-

Activity

-
-
-
-
- -
- -
-
-

Write three routines that perform, given a matrix $A$, the previous operations over matrices:

- -
-
-
-
- -
- -
-
-
    -
  • row_lamb(i, λ, A): i is the row to be changed, λ the multiplicative factor and A the matrix. This function should return the new matrix with the performed operation $(\lambda E_i)\rightarrow (E_i)$.
  • -
  • row_comb(i, j, λ, A): i is the row to be changed, j the row to be added, λ the multiplicative factor and A the matrix. This function should return the new matrix with the performed operation $(E_i + \lambda E_j)\rightarrow (E_i)$.
  • -
  • row_swap(i, j, A): i and j are the rows to be swapped. This function should return the new matrix with the performed operation $(E_i)\leftrightarrow (E_j)$.
  • -
- -
-
-
-
- -
- -
-
- -
-
-
-
- -
- -
-
- -
-
-
#Force the matrix has type float
-def row_lamb( i, λ, A ):
-    B = A.copy()
-    if isinstance(B[0,0],int64):
-        B=B.astype(float)
-    B[i] = λ*B[i]
-    return B
-
-def row_comb( i, j, λ, A ):
-    B = A.copy()
-    if isinstance(B[0,0],int64):
-        B=B.astype(float)
-    B[i] = λ*B[j] + B[i]
-    return B
-
-def row_swap( i, j, A ):
-    B = A.copy()
-    B[[i,j]] = B[[j,i]]
-    return B
-
- -
-
-
- -
-
- -
- -
-
-

Example

- -
-
-
-
- -
- -
-
- -
-
-
M1=np.array([[ 5, -4,  0],
-             [-4,  7, -3],
-             [ 0, -3,  5]])
-
- -
-
-
- -
-
- -
- -
-
-

Gaussian Elimination

-
-
-
-
- -
- -
-
-

Example 1

-
-
-
-
- -
- -
-
-

Using Kirchhoff's circuit laws, it is possible to solve the next system:

-

-

obtaining the next equations:

-\begin{align} -A:&&I_A( R+4R ) - I_B( 4R ) =& E \\ -C:&&-I_A( 4R ) + I_B( 4R + 3R ) - I_C(3R) =& 0 \\ -B:&&-I_B( 3R ) + I_C(3R+2R) =& -2E\, -\end{align}

or -\begin{align} -5\frac{I_A R }{E} - 4\frac{I_B R }{E} =& 1 \\ --4 \frac{I_A R }{E} + 7\frac{I_B R }{E} - 3 \frac{I_C R }{E} =& 0 \\ --3 \frac{I_B R }{E} + 5 \frac{I_C R }{E} =& -2\,. -\end{align}

-

Defining the variables $x_1 = R I_A/E$, $x_2 = R I_B/E$ and $x_3 = R I_C/E$ we have -\begin{align} -5x_1 - 4x_2 =& 1 \\ --4 x_1 + 7x_2 - 3 x_3 =& 0 \\ --3x_2 + 5 x_3 =& -2\,. -\end{align}

- -
-
-
-
- -
- -
-
-

A first method to solve linear systems of equations is the Gaussian elimination. This procedure consists of a set of recursive steps performed in order to diagonalise the matrix of the problem. A suitable way to introduce this method is applying it to some basic problem. To do so, let's take the result of the Example 1:

-$$ \left[ \matrix{ -5 & -4 & 0 \\ --4 & 7 & -3 \\ -0 & -3 & 5 -}\right] -\left[ \matrix{ -x_{1} \\ -x_{2} \\ -x_{3} -}\right] = -\left[ \matrix{ -1 \\ -0 \\ --2 -}\right]$$

Constructing the associated augmented matrix, we obtain

-$$ \left[ \matrix{ -5 & -4 & 0 & \vdots & 1 \\ --4 & 7 & -3 & \vdots & 0 \\ -0 & -3 & 5 & \vdots & -2 -}\right] $$ -
-
-
-
- -
- -
-
-

Activity

Use numpy functions to build the augmented matrix M1

- -
-
-
-
- -
- -
-
- -
-
-
M1 = np.array( [[5,-4,0],[-4,7,-3],[0,-3,5]] )
-sympy.Matrix(M1)
-
- -
-
-
- -
-
- -
-
- - - -
-$\displaystyle \left[\begin{matrix}5 & -4 & 0\\-4 & 7 & -3\\0 & -3 & 5\end{matrix}\right]$ -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
np.array( [[1],[0],[-2]] )
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[ 1],
-       [ 0],
-       [-2]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
M1_aug=np.hstack( (M1,[[1],[0],[-2]]))
-sympy.Matrix(M1_aug)
-
- -
-
-
- -
-
- -
-
- - - -
-$\displaystyle \left[\begin{matrix}5 & -4 & 0 & 1\\-4 & 7 & -3 & 0\\0 & -3 & 5 & -2\end{matrix}\right]$ -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
M1_aug=np.c_[ M1, [[1],[0],[-2]] ]
-sympy.Matrix(M1_aug)
-
- -
-
-
- -
-
- -
-
- - - -
-$\displaystyle \left[\begin{matrix}5 & -4 & 0 & 1\\-4 & 7 & -3 & 0\\0 & -3 & 5 & -2\end{matrix}\right]$ -
- -
-
-
-
- -
-
- -
- -
-
-

At this point, we can eliminate the coefficients of the variable $x_1$ in the second and third equations. For this, we apply the operations $\operatorname{Comb}(E_2,E_1,4/5)$.

-

$E_2$ → [-4,7,-3⋮0]+[4,-16/5,0⋮4/5]=[0,19/5,-3⋮4/5]

-

The coefficient in the third equation is already null. We then obtain:

-$$ \left[ \matrix{ -5 & -4 & 0 & \vdots & 1 \\ -0 & 19/5 & -3 & \vdots & 4/5 \\ -0 & -3 & 5 & \vdots & -2 -}\right] $$ -
-
-
-
- -
- -
-
- -
-
-
M1_LU=row_comb(1,0,4/5,M1_aug)
-M1_LU
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[ 5. , -4. ,  0. ,  1. ],
-       [ 0. ,  3.8, -3. ,  0.8],
-       [ 0. , -3. ,  5. , -2. ]])
-
- -
-
-
-
- -
-
- -
- -
-
-

Now, we proceed to eliminate the coefficient of $x_2$ in the third equation. For this, we apply again $\operatorname{Comb}(E_3,E_2,3\cdot 5/19)$

-

$E_3$ → [0,-3,5⋮-2]+[0,(3*5/19)*(19/5),-(3*5/19)*3⋮(3*5/19)*4/5]→[0,0,50/19⋮-26/19]

-$$ \left[ \matrix{ -5 & -4 & 0 & \vdots & 1 \\ -0 & 16/5 & -3 & \vdots & 4/5 \\ -0 & 0 & 50/19 & \vdots & -26/19 -}\right] $$ -
-
-
-
- -
- -
-
- -
-
-
M1_LU=row_comb(2,1,3*5/19,M1_LU)
-M1_LU
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
M1_LU
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[ 5.        , -4.        ,  0.        ,  1.        ],
-       [ 0.        ,  3.8       , -3.        ,  0.8       ],
-       [ 0.        ,  0.        ,  2.63157895, -1.36842105]])
-
- -
-
-
-
- -
-
- -
- -
-
-

The final step is to solve for $x_3$ in the last equation, doing the operation $\operatorname{Lamb}(E_3,19/50)$, yielding:

-$$ \left[ \matrix{ -5 & -4 & 0 & \vdots & 1 \\ -0 & 3.8 & -3 & \vdots & 0.8 \\ -0 & 0 & 1 & \vdots & -26/50 -}\right] $$

From this, it is direct to conclude that $x_3 = -26/50=-0.52$, for $x_2$ and $x_1$ it is only necessary to replace the found value of $x_3$.

- -
-
-
-
- -
- -
-
- -
-
-
row_lamb(2,19/50,M1_LU)
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[ 5.  , -4.  ,  0.  ,  1.  ],
-       [ 0.  ,  3.8 , -3.  ,  0.8 ],
-       [ 0.  ,  0.  ,  1.  , -0.52]])
-
- -
-
-
-
- -
-
- -
- -
-
-

Linear Systems of Equations

-
-
-
-
- -
- -
-
-

A linear system is a set of equations of $n$ variables that can be written in a general form:

-$$ a_{11}x_1 + a_{12}x_2 + \cdots +a_{1n}x_n = b_1 $$$$\vdots$$$$ a_{m1}x_1 + a_{m2}x_2 + \cdots +a_{mn}x_n = b_m $$

where $n$ is, again, the number of variables, and $m$ the number of equations.

-

A linear system has solution if and only if $m\geq n$. This leads us to the main objetive of a linear system, find the set $\{x_i\}_{i=0}^n$ that fulfills all the equations.

-

Although there is an intuitive way to solve this type of systems, by just adding and subtracting equations until reaching the desire result, the large number of variables of some systems found in physics and astronomy makes necessary to develop iterative and general approaches. Next, we shall introduce matrix and vector notation and some basic operations that will be the basis of the methods to be developed in this section.

-

Quadratic eqution...

- -
-
-
-
- -
- -
-
-

Matrices and vectors

-
-
-
-
- -
- -
-
-

A $m\times n$ matrix can be defined as a set of numbers arranged in columns and rows such as:

-$$ A = [a_{ij}] = \left[ \matrix{ -a_{11} & a_{12} & \cdots & a_{1n} \\ -a_{21} & a_{22} & \cdots & a_{2n} \\ -\vdots & \vdots & & \vdots\\ -a_{m1} & a_{m2} & \cdots & a_{mn} -}\right] $$

In the same way, it is possible to define a $n$-dimensional column vector as

-$$ \boldsymbol{x} = \left[ \matrix{ -x_{1} \\ -x_{2} \\ -\vdots\\ -x_{n} -}\right] $$

and a row vector

-$$ \boldsymbol{y} = \left[ \matrix{ -y_{1} & -y_{2} & -\cdots & -y_{n} -}\right] $$ -
-
-
-
- -
- -
-
-

The system of equations

-$$ a_{11}x_1 + a_{12}x_2 + \cdots a_{1n}x_n = b_1 $$$$\vdots$$$$ a_{m1}x_1 + a_{m2}x_2 + \cdots a_{mn}x_n = b_m $$

can be then written in a more convenient way as

-$$ A \textbf{x} = \left[ \matrix{ -a_{11} & a_{12} & \cdots & a_{1n} \\ -a_{21} & a_{22} & \cdots & a_{2n} \\ -\vdots & \vdots & & \vdots\\ -a_{m1} & a_{m2} & \cdots & a_{mn} -}\right] -\left[ \matrix{ -x_{1} \\ -x_{2} \\ -\vdots\\ -x_{n} -}\right] = \boldsymbol{b} = -\left[ \matrix{ -b_{1} \\ -b_{2} \\ -\vdots\\ -b_{n} -}\right]$$

We can also introducing the $n\times (n+1)$ augmented matrix as

-$$[A:\textbf{b}] = \left[ \matrix{ -a_{11} & a_{12} & \cdots & a_{1n} & \vdots & b_1 \\ -a_{21} & a_{22} & \cdots & a_{2n} & \vdots & b_2 \\ -\vdots & \vdots & & \vdots & \vdots & \vdots \\ -a_{m1} & a_{n2} & \cdots & a_{nn} & \vdots & b_n -}\right]$$ -
-
-
-
- -
- -
-
-

Implementation in Scipy

-
-
-
-
- -
- -
-
- -
-
-
import scipy
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
P,L,U=scipy.linalg.lu(M1_aug)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
U
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[ 5.        , -4.        ,  0.        ,  1.        ],
-       [ 0.        ,  3.8       , -3.        ,  0.8       ],
-       [ 0.        ,  0.        ,  2.63157895, -1.36842105]])
-
- -
-
-
-
- -
-
- -
- -
-
-

$x_3$ is now

- -
-
-
-
- -
- -
-
- -
-
-
x3=U[2,3]/U[2,2]
-'x3=-26/50={:.2f}'.format(x3)
-
- -
-
-
- -
-
- -
-
- - - -
-
'x3=-26/50=-0.52'
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
x2=(U[1,3]-U[1,2]*x3)/U[1,1]
-round(x2,2)
-
- -
-
-
- -
-
- -
-
- - - -
-$\displaystyle -0.2$ -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
x1=( U[0,3]-U[0,1]*x2-U[0,2]*x3 )/U[0,0]
-round(x1,2)
-
- -
-
-
- -
-
- -
-
- - - -
-$\displaystyle 0.04$ -
- -
-
-
-
- -
-
- -
- -
-
-

General Gaussian elimination

-
-
-
-
- -
- -
-
-

Now, we shall describe the general procedure for Gaussian elimination:

-
    -
  1. Give an augmented matrix $\hat{A}=[A:\textbf{b}]$.
  2. -
  3. Find the first non-zero coefficient $a_{i1}$ associated to $x_1$. This element is called pivot.
  4. -
  5. Apply the operation $\operatorname{Swap}(E_1,E_i)$. This guarantee the first row has a non-zero coefficient $a_{11}$.
  6. -
  7. Apply the operation $\operatorname{Comb}(E_j,E_1,-a_{j1}/a_{11})$. This eliminates the coefficients associated to $x_1$ in all the rows but in the first one.
  8. -
  9. Repeat steps 2. to 4. but for the coefficients of $x_2$ and then $x_3$ and so up to $x_n$. When iterating the coefficients of $x_{k}$, do not take into account the first $k$-th rows as they are already sorted.
  10. -
  11. Once you obtain a diagonal form of the matrix, apply the operation $\operatorname{Lamb}(E_n,1/a_{nn})$. This will make the coefficient of $x_n$ in the last equation equal to 1.
  12. -
  13. The final result should be an augmented matrix of the form: -$$\left[ \matrix{ -a_{11} & a_{12} & \cdots & a_{1(n-1)} & a_{1n} & \vdots & \hat b_1 \\ -0 & a_{22} & \cdots & a_{2(n-1)} & a_{2n} & \vdots & \hat b_2 \\ -\vdots & \vdots & & \vdots & \vdots & \vdots & \vdots \\ -0 & 0 & \cdots & a_{(n-1)(n-1)} & a_{(n-1)n} & \vdots & \hat b_{n-1} \\ -0 & 0 & \cdots & 0 & 1 & \vdots & \hat b_n -}\right]$$
  14. -
  15. The solution to the problem is then obtained through backward substitutions, i.e. -$$x_n = \hat b_n$$ -$$ x_{n-1} = \frac{\hat b_{n-1} - a_{(n-1)n}x_n}{a_{(n-1)(n-1)}}$$ -$$\vdots$$ -$$x_i = \frac{\hat b_i - \sum_{j=i+1}^n a_{ij}x_j}{a_{ii}}\ \ \ \ \mbox{for}\ \ \ i=n-1, n-2, \cdots, 1$$
  16. -
- -
-
-
-
- -
- -
-
-

See custom implementation of general Gaussian elimination

- -
-
-
-
- -
- -
-
- -
-
-
#Gaussian Elimination
-import scipy
-def Gaussian_Elimination( A0 ):
-    #Making local copy of matrix
-    P,L,A=scipy.linalg.lu(A0)
-    n = len(A)    
-    #Finding solution
-    x = np.zeros( n )
-    x[n-1] = A[n-1,n]
-    for i in xrange( n-1, -1, -1 ):
-        x[i] = ( A[i,n] - sum(A[i,i+1:n]*x[i+1:n]) )/A[i,i]
-    
-    #Upper diagonal matrix and solutions x
-    return A, x
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
np.random.seed(3)
-M =  np.random.random( (4,5) )
-M
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[0.5507979 , 0.70814782, 0.29090474, 0.51082761, 0.89294695],
-       [0.89629309, 0.12558531, 0.20724288, 0.0514672 , 0.44080984],
-       [0.02987621, 0.45683322, 0.64914405, 0.27848728, 0.6762549 ],
-       [0.59086282, 0.02398188, 0.55885409, 0.25925245, 0.4151012 ]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
U,x=Gaussian_Elimination(M)
-
- -
-
-
- -
-
- -
- -
-
-

Upper triangular

- -
-
-
-
- -
- -
-
- -
-
-
U
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[ 0.89629309,  0.12558531,  0.20724288,  0.0514672 ,  0.44080984],
-       [ 0.        ,  0.63097203,  0.16354802,  0.47919953,  0.62205662],
-       [ 0.        ,  0.        ,  0.52490983, -0.06699671,  0.21531002],
-       [ 0.        ,  0.        ,  0.        ,  0.32582312,  0.00303691]])
-
- -
-
-
-
- -
-
- -
- -
-
-

solutions

- -
-
-
-
- -
- -
-
- -
-
-
x
-
- -
-
-
- -
-
- -
-
- - - -
-
array([0.27395594, 0.8721633 , 0.41137442, 0.00932074])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
M1_aug
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[ 5, -4,  0,  1],
-       [-4,  7, -3,  0],
-       [ 0, -3,  5, -2]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
Gaussian_Elimination(M1_aug)
-
- -
-
-
- -
-
- -
-
- - - -
-
(array([[ 5.        , -4.        ,  0.        ,  1.        ],
-        [ 0.        ,  3.8       , -3.        ,  0.8       ],
-        [ 0.        ,  0.        ,  2.63157895, -1.36842105]]),
- array([ 0.04, -0.2 , -0.52]))
-
- -
-
-
-
- -
-
- -
- -
-
-

Pivoting Strategies

-
-
-
-
- -
- -
-
-

The previous method of Gaussian Elimination for finding solutions of linear systems is mathematically exact, however round-off errors that appear in computational arithmetics can represent a real problem when high accuracy is required.

-

In order to illustrate this, consider the next situation:

-$$ E_1: 0.00300x_1 + 59.14x_2 = 59.17 $$$$ E_2: 5.291x_1 - 6.130x_2 = 46.78 $$

Using four-digit arithmetic we obtain:

-

1. Constructing the augmented matrix:

-$$ \left[ \matrix{ -0.003 & 59.14 & \vdots & 59.17 \\ -5.291 & -6.130 & \vdots & 46.78 -}\right] $$

2. Applying the reduction with the first pivot, we obtain:

-$$(E_1 + m E_2)\rightarrow (E_1)$$

where:

-$$m = -\frac{a_{21}}{a_{11}} = -\frac{5.291}{0.003} = 1763.666\cdots \approx 1764$$

In this step, we have taken the first four digits. This leads us to:

-$$ \left[ \matrix{ -0.003 & 59.14 & \vdots & 59.17 \\ -0 & -104300 & \vdots & -104400 -}\right] $$

The exact system is instead

-$$ \left[ \matrix{ -0.003 & 59.14 & \vdots & 59.17 \\ -0 & -104309.37\bar{6} & \vdots & -104309.37\bar{6} -}\right] $$

Using the solution $x_2 \approx 1.001$, we obtain

-$$ x_1 \approx \frac{59.17 - (59.14)(1.001)}{0.00300} = -10 $$

The exact solution is however:

-$$ x_1 = 10.00 $$

The source of such a large error is that the factor $59.14/0.00300 \approx 20000$. This quantity is propagated through the combination steps of the Gaussian Elimination, yielding a complete wrong result.

- -
-
-
-
- -
- -
-
-

Computing time

-
-
-
-
- -
- -
-
-

As mentioned before, Algebra Linear methods do not invole numerical approximations excepting round-off errors. This implies the computing time depends on the number of involved operations (multiplications, divisions, additions and subtractions). It is possible to demonstrate that the numbers of required divisions/multiplications is given by:

-$$\frac{n^3}{3}+n^2-\frac{n}{3}$$

and the required additions/subtractions:

-$$\frac{n^3}{3}+\frac{n^2}{2}-\frac{5n}{6}$$

These numbers are calculated separately as the computing time per operation for divisions and multiplications are similar and much larger than computing times for additions and subtractions. According to this, the overall computing time, for large $n$, scales as $n^3$/3.

- -
-
-
-
- -
- -
-
-

Example 2

-
-
-
-
- -
- -
-
-

Using the library datetime of python, evaluate the computing time required for Gaussian_Elimination to find the solution of a system of $n=20$ equations and $20$ unknowns. For this purpose you can generate random systems. For a more robust result, repeat $500$ times, give a mean value and plot an histrogram of the computing times.

- -
-
-
-
- -
- -
-
- -
-
-
#Importing datatime
-from datetime import datetime
-
-#Number of repeats
-Nrep = 500
-#Size of matrix
-n = 20
-
-def Gaussian_Time( n, Nrep ):
-    #Arrays of times
-    Times = []
-    #Cicle for number of repeats
-    for i in xrange(Nrep):
-        #Generating random matrix
-        M = np.matrix( np.random.random( (n,n+1) ) )
-        
-        #Starting time counter
-        tstart = datetime.now()
-        #Invoking Gaussian Elimination routine
-        Gaussian_Elimination(M)
-        #Killing time counter
-        tend = datetime.now()
-        
-        #Saving computing time
-        Times.append( (tend-tstart).microseconds )
-        
-    #Numpy Array
-    Times = np.array(Times)
-    
-    print "The mean computing time for a %dx%d matrix is: %lf microseconds"%(n,n,Times.mean())
-    
-    #Histrogram
-    plt.figure( figsize=(8,5) )
-    histo = plt.hist( Times, bins = 30 )
-    plt.xlabel( "Computing Time [microseconds]" )
-    plt.ylabel( "Ocurrences" )
-    plt.grid()
-    
-    return Times.mean()
-    
-    
-Gaussian_Time( n, Nrep )
-
- -
-
-
- -
-
- -
-
- -
-
The mean computing time for a 20x20 matrix is: 2762.628000 microseconds
-
-
-
-
-
-
- - - -
-
2762.6280000000002
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Activity

-
-
-
-
- -
- -
-
-

Using the previous code, estimate the computing time for random matrices of size $n=5,10,50,100,500,1000$. For each size, compute $500$ times in order to reduce spurious errors. Plot the results in a figure of $n$ vs computing time. Is it verified the some of scaling laws (Multiplication/Division or Addition/Sustraction). Note that for large values of $n$, both scaling laws converge to the same.

- -
-
-
-
- -
- -
-
-
- -
-
-
-
- -
- -
-
-

Partial pivoting

-
-
-
-
- -
- -
-
-

A suitable method to reduce round-off errors is to choose a pivot more conveniently. As we saw before, a small pivot generally implies larger propagated errors as they appear usually as dividends. The partial pivoting method consists then of a choosing of the largest absolute coefficient associated to $x_i$ instead of the first non-null one, i.e.

-$$ |a_{ii}| = \max_{i\leq j\leq n}|a_{ji}| $$

This way, propagated multiplication errors would be minimized.

- -
-
-
-
- -
- -
-
-

Activity

-
-
-
-
- -
- -
-
-

Create a new routine Gaussian_Elimination_Pivoting from Gaussian_Elimination in order to include the partial pivoting method. Compare both routines with some random matrix and with the exact solution.

- -
-
-
-
- -
- -
-
-
- -
-
-
-
- -
- -
-
-

Matrix Inversion

-
-
-
-
- -
- -
-
-

Asumming a nonsingular matrix $A$, if a matrix $A^{-1}$ exists, with $AA^{-1} = I$ and $A^{-1}A = I$, where $I$ is the identity matrix, then $A^{-1}$ is called the inverse matrix of $A$. If such a matrix does not exist, $A$ is said to be a singular matrix.

-

A corollary of this definition is that $A$ is also the inverse matrix of $A^{-1}$.

-

Once defined the Gaussian Elimination method, it is possible to extend it in order to find the inverse of any nonsingular matrix. -Let's consider the next equation:

-$$ AA^{-1} = AB= \left[ \matrix{ -a_{11} & a_{12} & \cdots & a_{1n} \\ -a_{21} & a_{22} & \cdots & a_{2n} \\ -\vdots & \vdots & & \vdots\\ -a_{m1} & a_{n2} & \cdots & a_{nn} -}\right]\left[ \matrix{ -b_{11} & b_{12} & \cdots & b_{1n} \\ -b_{21} & b_{22} & \cdots & b_{2n} \\ -\vdots & \vdots & & \vdots\\ -b_{n1} & b_{n2} & \cdots & b_{nn} -}\right] = -\left[ \matrix{ -1 & 0 & \cdots & 0 \\ -0 & 1 & \cdots & 0 \\ -\vdots & \vdots & \ddots & \vdots\\ -0 & 0 & \cdots & 1 -}\right]$$

This can be rewritten as a set of $n$ systems of equations, i.e.

-$$ \left[ \matrix{ -a_{11} & a_{12} & \cdots & a_{1n} \\ -a_{21} & a_{22} & \cdots & a_{2n} \\ -\vdots & \vdots & & \vdots\\ -a_{n1} & a_{n2} & \cdots & a_{nn} -}\right]\left[ \matrix{ -b_{11} \\ -b_{21} \\ -\vdots \\ -b_{n1} -}\right] = -\left[ \matrix{ -1 \\ -0 \\ -\vdots \\ -0 -}\right],$$$$\left[ \matrix{ -a_{11} & a_{12} & \cdots & a_{1n} \\ -a_{21} & a_{22} & \cdots & a_{2n} \\ -\vdots & \vdots & & \vdots\\ -a_{n1} & a_{n2} & \cdots & a_{nn} -}\right]\left[ \matrix{ -b_{12} \\ -b_{22} \\ -\vdots \\ -b_{n2} -}\right] = -\left[ \matrix{ -0 \\ -1 \\ -\vdots \\ -0 -}\right]$$$$\vdots$$

-$$\left[ \matrix{ -a_{11} & a_{12} & \cdots & a_{1n} \\ -a_{21} & a_{22} & \cdots & a_{2n} \\ -\vdots & \vdots & & \vdots\\ -a_{n1} & a_{n2} & \cdots & a_{nn} -}\right]\left[ \matrix{ -b_{1n} \\ -b_{2n} \\ -\vdots \\ -b_{nn} -}\right] = -\left[ \matrix{ -0 \\ -0 \\ -\vdots \\ -1 -}\right]$$

-

These systems can be solved individually by using Gaussian Elimination, however we can mix all the problems, obtaining the augmented matrix:

-$$\left[ \matrix{ -a_{11} & a_{12} & \cdots & a_{1n} & \vdots & 1 & 0 & \cdots & 0 \\ -a_{21} & a_{22} & \cdots & a_{2n} & \vdots & 0 & 1 & \cdots & 0 \\ -\vdots & \vdots & & \vdots & \vdots & \vdots & \vdots & \ddots & \vdots\\ -a_{n1} & a_{n2} & \cdots & a_{nn} & \vdots & 0 & 0 & \cdots & 1 -}\right]$$

Now, applying Gaussian Elimination we can obtain a upper diagonal form for the first matrix. Completing the steps using forwards elimination we can convert the first matrix into the identity matrix, obtaining

-$$\left[ \matrix{ -1 & 0 & \cdots & 0 & \vdots & b_{11} & b_{12} & \cdots & b_{1n} \\ -0 & 1 & \cdots & 0 & \vdots & b_{21} & b_{22} & \cdots & b_{2n} \\ -\vdots & \vdots & \ddots & \vdots & \vdots & \vdots & \vdots & & \vdots\\ -0 & 0 & \cdots & 1 & \vdots & b_{n1} & b_{n2} & \cdots & b_{nn} -}\right]$$

Where the second matrix is then the inverse $B=A^{-1}$.

- -
-
-
-
- -
- -
-
-

Activity

-
-
-
-
- -
- -
-
-

Using the previous routine Gaussian_Elimination_Pivoting, create a new routine Inverse that calculates the inverse of any given squared matrix.

- -
-
-
-
- -
- -
-
-
- -
-
-
-
- -
- -
-
-

Determinant of a Matrix

-
-
-
-
- -
- -
-
-

The determinant of a matrix is a scalar quantity calculated for square matrix. This provides important information about the matrix of coefficients of a system of linear of equations. For example, any system of $n$ equations and $n$ unknowns has an unique solution if the associated determinant is nonzero. This also implies the determinant allows to evaluate whether a matrix is singular or nonsingular.

- -
-
-
-
- -
- -
-
-

Calculating determinants

-
-
-
-
- -
- -
-
-

Next, we shall define some properties of determinants that will allow us to calculate determinants by using a recursive code:

-

1. If $A = [a]$ is a $1\times 1$ matrix, its determinant is then $\det A = a$.

-

2. If $A$ is a $n\times n$ matrix, the minor matrix $M_{ij}$ is the determinant of the $(n-1)\times(n-1)$ matrix obtained by deleting the $i$th row and the $j$th column.

-

3. The cofactor $A_{ij}$ associated with $M_{ij}$ is defined by $A_{ij} = (-1)^{i+j}M_{ij}$.

-

4. The determinant of a $n\times n$ matrix $A$ is given by:

-$$ \det A = \sum_{j=1}^n a_{ij}A_{ij} $$

or

-$$ \det A = \sum_{i=1}^n a_{ij}A_{ij} $$

This is, it is possible to use both, a row or a column for calculating the determinant.

- -
-
-
-
- -
- -
-
-

Computing time of determinants

-
-
-
-
- -
- -
-
-

Using the previous recurrence, we can calculate the computing time of the previous algorithm. First, let's consider the number of required operations for a $2\times 2$ matrix: let $A$ be a $2\times 2$ matrix given by:

-$$ A = \left[ \matrix{ -a_{11} & a_{12} \\ -a_{21} & a_{22}}\right]$$

The determinant is then given by:

-$$\det(A) = a_{11}a_{22} - a_{12}a_{21}$$

the number of required multiplications was $2$ and subtractions is $1$.

-

Now, using the previous formula for the determinant

-$$ \det A = \sum_{j=1}^n a_{ij}A_{ij} $$

For a $3\times 3$ matrix, it is necessary to calculate $3$ times $2\times 2$ determinants. Besides, it is necessary to multiply the cofactor $A_{ij}$ with the coefficient $a_{ij}$, that leads us with $t_{n=3}=3\times 2 + 3$ multiplications. Additions are not important as their computing time is far less than multiplications.

-

For a $4\times 4$ matrix, we need four deteminants of $3\times 3$ submatrices, leading $t_{n=4} = 4\times( 3\times 2 + 3 ) + 4 = 4! + \frac{4!}{2!} + \frac{4!}{3!}$. In general, for a $n\times n$ matrix, we have then:

-$$ t_{n} = \frac{n!}{(n-1)!} + \frac{n!}{(n-2)!} + \cdots + \frac{n!}{1!} = n!\left( \sum_{i=1}^{n-1}\frac{1}{i!} \right)$$

If $n$ is large enough, we can approximate $t_{n}\approx n!$.

-

In computers, this is a prohibitive computing time so other schemes have to be proposed.

- -
-
-
-
- -
- -
-
-

Activity

-
-
-
-
- -
- -
-
-

Evaluate the computing time of the Determinant routine for matrix sizes of $n=1,2,3,\cdots,10$ and doing several repeats. Plot your result ($n$ vs $t_n$). What can you conclude about the behaviour of the computing time?

- -
-
-
-
- -
- -
-
-

Properties of determinants

-
-
-
-
- -
- -
-
-

Determinants have a set of properties that can reduce considerably computing times. Suppose $A$ is a $n\times n$ matrix:

-

1. If any row or column of $A$ has only zero entries, then $\det A = 0$.

-

2. If two rows or columns of $A$ are the same, then $\det A = 0$.

-

3. If $\hat A$ is obtained from $A$ by using a swap operation $(E_i)\leftrightarrow (E_j)$, then $\det \hat A=-\det A$.

-

4. If $\hat A$ is obtained from $A$ by using a escalation operation $(\lambda E_i)\leftrightarrow (E_i)$, then $\det \hat A=\lambda \det A$.

-

5. If $\hat A$ is obtained from $A$ by using a combination operation $(E_i+\lambda E_j) \leftrightarrow (E_i)$, then $\det \hat A=\det A$.

-

6. If $B$ is also a $n\times n$ matrix, then $\det(AB)=(\det A)(\det B).$

-

7. $\det A^t=\det A.$

-

8. $\det A^{-1}=(\det A)^{-1}$

-

9. Finally and most importantly: if $A$ is an upper, lower or diagonal matrix, then:

-$$ \det A = \prod_{i=1}^n a_{ii} $$ -
-
-
-
- -
- -
-
-

As we analysed before, Gaussian Elimination takes a computing time scaling like $n^3$ for large matrix sizes. According to the previous properties, the determinant of a upper diagonal matrix just takes $n-1$ multiplications, far less than a nondiagonal matrix. Combining these properties, we can track back and relate the determinant of the resulting upper diagonal matrix and the original one. Leading us to a computing time scaling like $n^3$, much better than the original $n!$.

- -
-
-
-
- -
- -
-
-

Activity

-
-
-
-
- -
- -
-
-

Using the Gaussian_Elimination routine and tracking back the performed operations, construct a new routine called Gaussian_Determinant. Make the same analysis of the computing time as the previous activity. Compare both results.

- -
-
-
-
- -
- -
-
-

Existence of inverse

A matrix $A$ has an inverse if $\det{A}\ne 0$. See for example here

-

If the matrix $A$ has an inverse, then -\begin{align} -A \boldsymbol{x}=&\boldsymbol{b}\\ -A^{-1}A\boldsymbol{x}=&A^{-1}\boldsymbol{b}\\ -\boldsymbol{x}=&A^{-1}\boldsymbol{b}\,, -\end{align}

-

Example -From the previous example

- -
-
-
-
- -
- -
-
- -
-
-
np.random.seed(3)
-M =  np.random.random( (4,5) )
-M
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[0.5507979 , 0.70814782, 0.29090474, 0.51082761, 0.89294695],
-       [0.89629309, 0.12558531, 0.20724288, 0.0514672 , 0.44080984],
-       [0.02987621, 0.45683322, 0.64914405, 0.27848728, 0.6762549 ],
-       [0.59086282, 0.02398188, 0.55885409, 0.25925245, 0.4151012 ]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
M[:,0]
-
- -
-
-
- -
-
- -
-
- - - -
-
array([0.5507979 , 0.89629309, 0.02987621, 0.59086282])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
np.c_[M[:,0]]
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[0.5507979 ],
-       [0.89629309],
-       [0.02987621],
-       [0.59086282]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
A=np.c_[ tuple( [ np.c_[M[:,i]]    for i in range(4) ] ) ]
-A
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[0.5507979 , 0.70814782, 0.29090474, 0.51082761],
-       [0.89629309, 0.12558531, 0.20724288, 0.0514672 ],
-       [0.02987621, 0.45683322, 0.64914405, 0.27848728],
-       [0.59086282, 0.02398188, 0.55885409, 0.25925245]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
b=np.c_[ M[:,4] ]
-b
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[0.89294695],
-       [0.44080984],
-       [0.6762549 ],
-       [0.4151012 ]])
-
- -
-
-
-
- -
-
- -
- -
-
-

such that -\begin{align} -A \boldsymbol{x}=&\boldsymbol{b}\,, -\end{align}

-

Check that $A$ has an inverse and calculate $\boldsymbol{x}$

- -
-
-
-
- -
- -
-
- -
-
-
Latex(r'$\det(A)={:.3f}\ne 0$'.format(np.linalg.det(A)))
-
- -
-
-
- -
-
- -
-
- - -
- -
- -
-
-
-
- - - -
-$$\det(A)=-0.097\ne 0$$ -
- -
-
-
-
- -
-
- -
- -
-
-

$\boldsymbol{x}=$

- -
-
-
-
- -
- -
-
- -
-
-
sympy.Matrix( np.dot( np.linalg.inv(A) , b).round(4) ) 
-
- -
-
-
- -
-
- -
-
- - - -
-$\displaystyle \left[\begin{matrix}0.274\\0.8722\\0.4114\\0.0093\end{matrix}\right]$ -
- -
-
-
-
- -
-
- -
- -
-
-

Numpy implementation

-
-
-
-
- -
- -
-
- -
-
-
np.linalg.solve(A,b)
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[0.27395594],
-       [0.8721633 ],
-       [0.41137442],
-       [0.00932074]])
-
- -
-
-
-
- -
-
- -
- -
-
-

Matrix diagonalization

See linear-algebra-diagonalization

- -
-
-
-
- -
- -
-
-
- -
-
-
-
- -
- -
-
-

LU Factorization

-
-
-
-
- -
- -
-
-

As we saw before, the Gaussian Elimination algorithm takes a computing time scaling as $\mathcal{O}(n^3/3)$ in order to solve a system of $n$ equations and $n$ unknowns. Let's assume a system of equations $\mathbf{A}\mathbf{x} = \mathbf{b}$ where $\mathbf{b}$ is already in upper diagonal form.

-$$\left[ \matrix{ -a_{11} & a_{12} & \cdots & a_{1(n-1)} & a_{1n} & \vdots & \hat b_1 \\ -0 & a_{22} & \cdots & a_{2(n-1)} & a_{2n} & \vdots & \hat b_2 \\ -\vdots & \vdots & & \vdots & \vdots & \vdots & \vdots \\ -0 & 0 & \cdots & a_{(n-1)(n-1)} & a_{(n-1)n} & \vdots & \hat b_{n-1} \\ -0 & 0 & \cdots & 0 & a_{nn} & \vdots & \hat b_n -}\right]$$

The Gauss-Jordan algorithm can reduce even more this problem in order to solve it directly, yielding:

-$$\left[ \matrix{ -1 & 0 & \cdots & 0 & 0 & \vdots & x_1 \\ -0 & 1 & \cdots & 0 & 0 & \vdots & x_2 \\ -\vdots & \vdots & & \vdots & \vdots & \vdots & \vdots \\ -0 & 0 & \cdots & 1 & 0 & \vdots & x_{n-1} \\ -0 & 0 & \cdots & 0 & 1 & \vdots & x_n -}\right]$$

From the upper diagonal form to the completely reduced one, it is necessary to perform $n+(n-1)+(n-2)+\cdots\propto n(n-1)$ backwards substitutions. The computing time for solving a upper diagonal system is then $\mathcal{O}(n^2)$.

-

Now, let $\mathbf{A}\mathbf{x} = \mathbf{b}$ be a general system of equations of $n$ dimensions. Let's assume $\mathbf{A}$ can be written as a multiplication of two matrices, one lower diagonal $\mathbf{L}$ and other upper diagonal $\mathbf{U}$, such that $\mathbf{A}=\mathbf{L}\mathbf{U}$. Defining a vector $\mathbf{y} = \mathbf{U}\mathbf{x}$, it is obtained for the original system

-$$ \mathbf{A} \mathbf{x}=\mathbf{L}(\mathbf{U}\mathbf{x}) = \mathbf{L}\mathbf{y} = \mathbf{b}$$

For solving this system we can then:

-

1. Solve the equivalent system $\mathbf{L}\mathbf{y} = \mathbf{b}$, what takes a computing time of $\mathcal{O}(n^2)$.

-

2. Once we know $\mathbf{y}$, we can solve the system $\mathbf{U}\mathbf{x} = \mathbf{y}$, with a computing time of $\mathcal{O}(n^2)$.

-

The global computing time is then $\mathcal{O}(2n^2)$

- -
-
-
-
- -
- -
-
-

Activity

-
-
-
-
- -
- -
-
-

In order to compare the computing time that Gaussian Elimination takes and the previous time for the LU factorization, make a plot of both computing times. What can you conclude when $n$ becomes large enough?

- -
-
-
-
- -
- -
-
-

Derivation of LU factorization

-
-
-
-
- -
- -
-
-

Although the LU factorization seems to be a far better method for solving linear systems as compared with say Gaussian Elimination, we was assuming we already knew the matrices $\mathbf{L}$ and $\mathbf{U}$. Now we are going to see the algorithm for perfoming this reduction takes a computing time of $\mathcal{O}(n^3/3)$.

-

You may wonder then, what advantage implies the use of this factorization? Well, matrices $\mathbf{L}$ and $\mathbf{U}$ do not depend on the specific system to be solved, i.e. there is not dependence on the $\mathbf{b}$ vector, so once we have both matrices, we can use them to solve any system we want, just taking a $\mathcal{O}(2n^2)$ computing time.

-

First, let's assume a matrix $\mathbf{A}$ with all its pivots are nonzero, so there is not need to swap rows. Now, when we want to eliminate all the coefficients associated to $x_1$, we perform the next operations:

-$$ (E_j-m_{j1}E_1)\rightarrow (E_j), \ \ \ \ \mbox{where}\ \ \ \ m_{j1} = \frac{a^{(1)}_{j1}}{a^{(1)}_{11}} $$

henceforth, $a^{(1)}_{ij}$ denotes the components of the original matrix $\mathbf{A}=\mathbf{A}^{(1)}$, $a^{(2)}_{ij}$ the components of the matrix after eliminating the coefficients of $x_1$, and generally, $a^{(k)}_{ij}$ the components of the matrix after eliminating the coefficients of $x_{k-1}$.

-

The previous operation over the matrix $\mathbf{A}$ can be also reproduced defining the matrix $\mathbf{M}^{(1)}$

-$$\mathbf{M}^{(1)} = \left[ \matrix{ -1 & 0 & \cdots & 0 & 0 \\ --m_{21} & 1 & \cdots & 0 & 0 \\ -\vdots & \vdots & \ddots & \vdots & \vdots \\ --m_{(n-1)1} & 0 & \cdots & 1 & 0 \\ --m_{n1} & 0 & \cdots & 0 & 1 -}\right]$$

This is called the first Gaussian transformation matrix. From this, we have

-$$ \mathbf{A}^{(2)}\mathbf{x} = \mathbf{M}^{(1)}\mathbf{A}^{(1)}\mathbf{x} = \mathbf{M}^{(1)}\mathbf{b}^{(1)} = \mathbf{b}^{(2)} $$

where $\mathbf{A}^{(2)}$ is matrix with null coefficients associated to $x_1$ but the first one.

-

Repeating the same procedure for the next pivots, we obtain then

-$$ \mathbf{A}^{(n)} = \mathbf{M}^{(n-1)}\mathbf{M}^{(n-2)}\cdots \mathbf{M}^{(1)}\mathbf{A}^{(1)} $$

where the $k$th Gaussian transformation matrix is defined as

-$$\mathbf{M}^{(k)}_{ij} = \left\{ \matrix{ -1 & \mbox{if}\ \ i=j \\ --m_{ij} & \mbox{if}\ \ j=k\ \ \mbox{and}\ \ k+1\leq i \leq n \\ -0 & \mbox{otherwise} -} \right.$$

and

-$$m_{ij} = \frac{a^{(j)}_{ij}}{a^{(j)}_{jj}} $$

Note $\mathbf{A}^{(n)}$ is a upper diagonal matrix given by

-$$\mathbf{A}^{(n)} = \left[ \matrix{ -a_{11}^{(n)} & a_{12}^{(n)} & \cdots & a_{1(n-1)}^{(n)} & a_{1n}^{(n)}\\ -0 & a_{22}^{(n)} & \cdots & a_{2(n-1)}^{(n)} & a_{2n}^{(n)} \\ -\vdots & \vdots & & \vdots & \vdots &\\ -0 & 0 & \cdots & a_{(n-1)(n-1)}^{(n)} & a_{(n-1)n}^{(n)} \\ -0 & 0 & \cdots & 0 & a_{nn}^{(n)} -}\right]$$

so we can define $\mathbf{U}\equiv \mathbf{A}^{(n)}$.

-

Now, taking the equation

-$$ \mathbf{A}^{(n)} = \mathbf{M}^{(n-1)}\mathbf{M}^{(n-2)}\cdots \mathbf{M}^{(1)}\mathbf{A}^{(1)} $$

and defining the inverse of $\mathbf{M}^{(k)}$ as

-$$ \mathbf{L}^{(k)}_{ij} = \left(\mathbf{M}^{(k)}\right)^{-1}_{ij} = \left\{ \matrix{ -1 & \mbox{if}\ \ i=j \\ -m_{ij} & \mbox{if}\ \ j=k\ \ \mbox{and}\ \ k+1\leq i \leq n \\ -0 & \mbox{otherwise} -} \right.$$

we obtain

-$$ \mathbf{L}^{(1)} \cdots \mathbf{L}^{(n-2)}\mathbf{L}^{(n-1)}\mathbf{A}^{(n)} = \mathbf{L}^{(1)} \cdots \mathbf{L}^{(n-2)}\mathbf{L}^{(n-1)}\mathbf{M}^{(n-1)}\mathbf{M}^{(n-2)}\cdots \mathbf{M}^{(1)}\mathbf{A}^{(1)} = \mathbf{L}\mathbf{U} $$

where the lower diagonal matrix $\mathbf{L}$ is given by:

-$$ \mathbf{L} = \mathbf{L}^{(1)} \cdots \mathbf{L}^{(n-2)}\mathbf{L}^{(n-1)} $$

.

- -
-
-
-
- -
- -
-
-

Algorithm for LU factorization

-
-
-
-
- -
- -
-
-

The algorithm is then given by:

-

1. Give a square matrix $\mathbf{A}$ where the pivots are nonzero.

-

2. Apply the operation $Comb(E_j,E_1,-a^{(1)}_{j1}/aa^{(1)}_{11})$. This eliminates the coefficients associated to $x_1$ in all the rows but in the first one.

-

3. Construct the matrix $\mathbf{L}^{(1)}$ given by

-$$ \mathbf{L}^{(k)}_{ij} = \left\{ \matrix{ -1 & \mbox{if}\ \ i=j \\ -m_{ij} = \frac{a^{(j)}_{ij}}{a^{(j)}_{jj}} & \mbox{if}\ \ j=k\ \ \mbox{and}\ \ k+1\leq i \leq n \\ -0 & \mbox{otherwise} -} \right.$$

with $k=1$.

-

4. Repeat the steps 2 and 3 for the next column until reaching the last one.

-

5. Return the matrices $\mathbf{U} = \mathbf{A}^{(n)}$ and $ \mathbf{L} = \mathbf{L}^{(1)} \cdots \mathbf{L}^{(n-2)}\mathbf{L}^{(n-1)} $.

- -
-
-
-
- -
- -
-
-

Activity

-
-
-
-
- -
- -
-
-

Create a routine called LU_Factorization that, given a matrix $\mathbf{A}$ and the previous algorithm, calculate the LU factorization of the matrix. Test your routine with a random square matrix, verify that $\mathbf{A} = \mathbf{L}\mathbf{U}$.

- -
-
-
-
- -
- -
-
-
- -
-
-
-
- -
- -
-
- -
-
-
M1
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[ 5, -4,  0],
-       [-4,  7, -3],
-       [ 0, -3,  5]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
import scipy
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
P,L,U=scipy.linalg.lu(M1)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
U
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[ 5.        , -4.        ,  0.        ],
-       [ 0.        ,  3.8       , -3.        ],
-       [ 0.        ,  0.        ,  2.63157895]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
The same obtained before
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
scipy.linalg.lu?
-
- -
-
-
- -
-
- -
- -
-
-

Eigenvalues and Eigenvectors activity

-
-
-
-
- -
- -
-
-

Electron interacting with a magnetic field

An electron is placed to interact with an uniform magnetic field. To give account of the possible allowed levels of the electron in the presence of the magnetic field it is necessary to solve the next equation

-\begin{equation} -\hat{H}|\Psi\rangle = E|\Psi\rangle -\end{equation}

where the hamiltonian is equal to $H = -\mu \cdot B = -\gamma B \cdot S$, with the gyromagnetic ratio $\gamma$, $\textbf{B}$ the magnetic field and $\textbf{S}$ the spin. It can be shown that the hamiltonian expression is transformed in

-\begin{equation} -\hat{\textbf{H}} = - \frac{\gamma \hbar}{2} \left( \begin{array}{cc} -B_z & B_x -i B_y \\ -B_x + i B_y & -B_z \end{array} \right) -\end{equation}

Then, by solving the problem $|H - EI|=0$ is found the allowed energy levels, i.e., finding the determinant of the -matrix $H - EI$ allows to get the values $E_1$ and $E_2$.

-

And solving the problem $\hat{H}\Psi$ - E$\Psi = 0$ gives the autofunctions $\Psi$, i.e., the column vector $\Psi= \{\Psi_1, \Psi_2\}$.

-

The function scipy.optimize.root can be used to get roots of a given equation. The experimental value of $\gamma$ for the electron is 2. The order of magnitude of the magnetic field is $1g$.

-

1) Find the allowed energy levels.

-

2) Find the autofunctions and normalize them.

-

Hint: An imaginary number in python can be written as 1j.

- -
-
-
-
- - - - -
- \ No newline at end of file diff --git a/_build/features/matplotlib.html b/_build/features/matplotlib.html deleted file mode 100644 index 8d8e558..0000000 --- a/_build/features/matplotlib.html +++ /dev/null @@ -1,9584 +0,0 @@ ---- -interact_link: content/features/matplotlib.ipynb -kernel_name: python3 -kernel_path: content/features -has_widgets: false -title: |- - Visualization with matplotlib -pagenum: 4 -prev_page: - url: /features/Pandas.html -next_page: - url: /features/ipython-notebooks.html -suffix: .ipynb -search: matplotlib colab figures gallery basic research google com interface src python ipython easy formating very href github restrepo computationalmethods blob master material ipynb target parentimg assets badge svg alt open div org plotting interactive scripts user things power etc matlab control line properties via functions appealing allowing always animmations example style float right markdown img static logo png d library produces publication quality variety hardcopy formats environments across platforms used shell web application servers six graphical toolkits tries hard possible generate plots histograms spectra bar charts errorcharts scatterplots just few lines code sampling screenshots thumbnail examples directory simple pyplot provides - -comment: "***PROGRAMMATICALLY GENERATED, DO NOT EDIT. SEE ORIGINAL FILES IN /content***" ---- - -
-
Visualization with matplotlib
-
-
- -
-
-

Open In Colab

- -
-
-
-
- -
- -
-
-

Matplotlib

-

Open In Colab

- -
-
-
-
- -
- -
-
-

Matplotlib is a python 2D plotting library which produces publication quality figures in a variety of hardcopy formats and interactive environments across platforms. matplotlib can be used in python scripts, the python and ipython shell, web application servers, and six graphical user interface toolkits.

-

Matplotlib tries to make easy things easy and hard things possible. You can generate plots, histograms, power spectra, bar charts, errorcharts, scatterplots, etc, with just a few lines of code. For a sampling, see the screenshots, thumbnail gallery, and examples directory

-

For simple plotting the pyplot interface provides a MATLAB-like interface, particularly when combined with IPython. For the power user, you have full control of line styles, font properties, axes properties, etc, via an object oriented interface or via a set of functions familiar to MATLAB users.

-

Official page

- -
-
-
-
- -
- -
- -
-
-
- -
- -
-
-

Basic Use

-
-
-
-
- -
- -
-
-

One of the most appealing advantages of Matplotlib is its versatility. You can use it in a very basic way as well as in a very customizable way, allowing a total control of what we want to sketch. We illustrate here some of the basic functions.

- -
-
-
-
- -
- -
-
- -
-
-
#Importing numpy
-import numpy as np
-#Ignore me!! (for scripts)
-%pylab inline
-#Importing matplotlib
-import matplotlib.pyplot as plt
-
- -
-
-
- -
-
- -
-
- -
-
Populating the interactive namespace from numpy and matplotlib
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
%pylab inline
-
- -
-
-
- -
-
- -
-
- -
-
Populating the interactive namespace from numpy and matplotlib
-
-
-
-
-
-
- -
-
- -
- -
-
-

The line %pylab inline is always necessary when using a IPython notebook. If you are working on the interpreter or with scripts, always use the function plt.show() in order to display the resulting image.

- -
-
-
-
- -
- -
-
- -
-
-
#Ploting a function
-x = np.linspace( 0, 2*np.pi, 500 )
-y = np.sin( x )
-plt.plot( x, y )
-#plt.plot( x, y,'.' )
-
- -
-
-
- -
-
- -
-
- - - -
-
[<matplotlib.lines.Line2D at 0x7f35a49404e0>]
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#Scatter of points
-X = np.random.random(200)
-Y = np.random.random(200)
-plt.plot( X, Y,'ro')
-
- -
-
-
- -
-
- -
-
- - - -
-
[<matplotlib.lines.Line2D at 0x7f35a4899400>]
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#Multiple plots
-#Ploting a function
-x = np.linspace( 0, 2*np.pi, 100 )
-plt.plot( x, np.sin( x ) )
-plt.plot( x, np.cos( x ) )
-
- -
-
-
- -
-
- -
-
- - - -
-
[<matplotlib.lines.Line2D at 0x7f35a404c898>]
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#Logaritmic axis Y
-x = np.linspace( 1, 10, 10 )
-plt.semilogy( x, np.exp( x ) )
-p=plt.semilogy( x, np.exp( x ),'.' )
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
p[0]
-
- -
-
-
- -
-
- -
-
- - - -
-
<matplotlib.lines.Line2D at 0x7f359ee7c908>
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
x
-
- -
-
-
- -
-
- -
-
- - - -
-
array([ 1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10.])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
np.exp(x)
-
- -
-
-
- -
-
- -
-
- - - -
-
array([2.71828183e+00, 7.38905610e+00, 2.00855369e+01, 5.45981500e+01,
-       1.48413159e+02, 4.03428793e+02, 1.09663316e+03, 2.98095799e+03,
-       8.10308393e+03, 2.20264658e+04])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#Logaritmic axis X
-x = np.linspace( 1, 10, 100 )
-plt.semilogx( x, np.log( x ) )
-
- -
-
-
- -
-
- -
-
- - - -
-
[<matplotlib.lines.Line2D at 0x7f359ec94518>]
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#Double Logaritmic axis
-x = np.linspace( 0.1, 16.5*np.pi, 200 )
-plt.loglog( x, np.sin( x )**2 )
-plt.loglog( x, np.sin( x )**2,'.' )
-
- -
-
-
- -
-
- -
-
- - - -
-
[<matplotlib.lines.Line2D at 0x7f359ec514a8>]
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#Double Logaritmic axis
-x = np.logspace( np.log10(0.1), np.log10(16.5*np.pi), 200 )
-plt.loglog( x, np.sin( x )**2 )
-plt.loglog( x, np.sin( x )**2,'.' )
-
- -
-
-
- -
-
- -
-
- - - -
-
[<matplotlib.lines.Line2D at 0x7ffb7c296978>]
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#Polar plots
-r = np.arange( 0, 3.0, 0.01 )
-theta = 2*np.pi*r
-
-plt.subplot(111, polar=True)
-plt.plot( theta, r )
-
- -
-
-
- -
-
- -
-
- - - -
-
[<matplotlib.lines.Line2D at 0x7f359ef9dda0>]
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#Fill between
-x = np.arange( 0, 2, 0.1 )
-y1 = x/2.
-y2 = x**2 + 1
-plt.fill_between( x, y1, y2,alpha=0.6 )
-
- -
-
-
- -
-
- -
-
- - - -
-
<matplotlib.collections.PolyCollection at 0x7f359ef43b00>
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#Multiple figures
-X = np.arange( 0, 10, 0.1 )
-#First plot
-plt.subplot( 1, 2, 1 )
-plt.plot( X, X**2+1 )
-#Second plot
-plt.subplot( 1, 2, 2 )
-plt.semilogy( X, np.exp(X-10) )
-
- -
-
-
- -
-
- -
-
- - - -
-
[<matplotlib.lines.Line2D at 0x7f359eb243c8>]
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#Histograms
-X = np.random.random( 500 )
-plt.hist( X )
-
- -
-
-
- -
-
- -
-
- - - -
-
(array([54., 54., 48., 53., 40., 53., 47., 46., 51., 54.]),
- array([0.0026303 , 0.10221054, 0.20179078, 0.30137101, 0.40095125,
-        0.50053148, 0.60011172, 0.69969195, 0.79927219, 0.89885243,
-        0.99843266]),
- <BarContainer object of 10 artists>)
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-
- -
-
-
-
- - - -
- -
-
- -
-
-
import matplotlib.pyplot as plt
-import matplotlib.animation
-import numpy as np
-
-t = np.linspace(0,2*np.pi)
-x = np.sin(t)
-
-fig, ax = plt.subplots()
-ax.axis([0,2*np.pi,-1,1])
-l, = ax.plot([],[])
-
-def animate(i):
-    l.set_data(t[:i], x[:i])
-
-#Avoid intial plot
-plt.close()
-ani = matplotlib.animation.FuncAnimation(fig, animate, frames=len(t))
-
-from IPython.display import HTML
-HTML(ani.to_jshtml())
-
- -
-
-
- -
-
- -
-
- - -
- - - - - - -
- -
- -
- - - - - - - - - -
-
- - - - - - -
-
-
- - - - -
- -
-
-
-
- -
-
- -
- -
-
-

Easy animmations with video output

-
-
-
-
- -
- -
-
- -
-
-
#See 
-from IPython.display import HTML
-from matplotlib import pyplot as plt
-from celluloid import Camera
-
-plt.ioff()
-fig = plt.figure()
-camera = Camera(fig)
-for i in range(10):
-    plt.plot([i] * 10)
-    camera.snap()
-plt.close()
-animation = camera.animate()
-animation.save('animation.mp4')
-HTML(animation.to_html5_video())
-
- -
-
-
- -
-
- -
-
- - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Formating Figures

-
-
-
-
- -
- -
-
-

Matplotlib supports complex formatting, even allowing LaTeX expressions. These features makes Matplotlib a very appealing package for making professional figures, for example for a scientific paper. Next it is shown an example (script) where you can see some of the capabilities of Matplotlib

- -
-
-
-
- -
- -
-
- -
-
-
#! /usr/bin/python
-#====================================================================
-#Importing libraries
-#====================================================================
-import numpy as np
-import matplotlib.pyplot as plt
-
-#Arrays
-X = np.linspace( 0, 10, 100 )
-Y = X**0.5
-Y1 = Y+0.5*(1+np.random.random(100))
-Y2 = Y-0.5*(1+np.random.random(100))
-
-#Setting the figure environment
-plt.figure( figsize = (16,6) )
-
-#====================================================================
-#First plot
-#====================================================================
-plt.subplot( 1, 2, 1 )
-plt.plot( X, Y )
-plt.title( "This is an unformatted plot" )
-
-#====================================================================
-#Second plot
-#====================================================================
-plt.subplot( 1, 2, 2 )
-#2D Plots
-plt.plot( X, Y, linewidth=4, color="green", label="Function" )
-plt.plot( X, Y1, linewidth=2, color="green" )
-plt.plot( X, Y2, linewidth=2, color="green" )
-#Error region
-plt.fill_between( X, Y1, Y2, color="green", alpha=0.2 )
-#Grid
-plt.grid( True )
-#X-axis limits
-plt.xlim( (0, 10) )
-#Y-axis limits
-plt.ylim( (0, 5) )
-#Label
-plt.legend( loc="upper left", fontsize=16 )
-#X label
-plt.xlabel( "$x$ coordinate", fontsize=20 )
-#Y label
-plt.ylabel( "$\sqrt{x}$", fontsize=20 )
-#Title
-plt.title( "This is a formatted plot", fontsize=16 )
-
-#====================================================================
-#Showing
-#====================================================================
-#You can store this figure in any format, even in vectorial formats 
-#like pdf
-plt.savefig( "Figure.pdf" )
-#Showing the figure on screen
-plt.show()
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-
- -
-
-
-
- -
- -
-
-

Gallery

-
-
-
-
- -
- -
-
-

This gallery comprehends some interesting advanced uses of matplotlib.

- -
-
-
-
- -
- -
-
- -
-
-
from IPython.core.display import Image 
-Image(filename='./figures/voids.png')
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
Image(filename='./figures/VPHphase.png')
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
Image(filename='./figures/simulation.png')
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
Image(filename='./figures/voiddensity.png')
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
Image(filename='./figures/halosfraction.png')
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-
- -
-
-
-
- - - - -
- \ No newline at end of file diff --git a/_build/features/medium_modelling_part_one.html b/_build/features/medium_modelling_part_one.html deleted file mode 100644 index 652e735..0000000 --- a/_build/features/medium_modelling_part_one.html +++ /dev/null @@ -1,507 +0,0 @@ ---- -redirect_from: - - "/features/medium-modelling-part-one" -interact_link: content/features/medium_modelling_part_one.ipynb -kernel_name: python3 -kernel_path: content/features -has_widgets: false -title: |- - SIR Model -pagenum: 24 -prev_page: - url: /features/differential-equations.html -next_page: - url: /features/statistics.html -suffix: .ipynb -search: d infected com t colab r google cdot model github blob master beta frac research ipynb s restrepo sir n person gamma href computationalmethods material mediummodellingpartone target parentimg src assets badge svg alt open hf infectiousdiseasemodelling license scholar compartmental population susceptible recovered total infects per disease used covid understanding align partone bibliography introduction mathematical epidemiology m martcheva springer co scholarlookup title anintroductiontomathematicalepidemiologyauthor mmartcheva pdf drive file ggeqrkxada eqozemflbcsqmkrk view usp sharing separates into several compartments example still healthy already cannot get again require following parameters expected amount days spread proportion recovering basic reproduction just intuitive formula check colombia models coronavirus - -comment: "***PROGRAMMATICALLY GENERATED, DO NOT EDIT. SEE ORIGINAL FILES IN /content***" ---- - -
-
SIR Model
-
-
- -
-
-

Open In Colab

- -
-
-
-
- - - -
- -
-
- -
-
-
from scipy.integrate import odeint
-import numpy as np
-import matplotlib.pyplot as plt
-%matplotlib inline 
-#!pip install mpld3
-import mpld3
-mpld3.enable_notebook()
-
- -
-
-
- -
-
- -
- -
-
-

compartmental model.

A compartmental model separates the population into several compartments, for example:

-
    -
  • Susceptible (can still be infected, “healthy”)
  • -
  • Infected
  • -
  • Recovered (were already infected, cannot get infected again)
  • -
-

We require the following parameters

-
    -
  • $N$: total population
  • -
  • $S(t)$: number of people susceptible on day t
  • -
  • $I(t)$: number of people infected on day t
  • -
  • $R(t)$: number of people recovered on day t
  • -
  • $\beta$: expected amount of people an infected person infects per day
  • -
  • $D$: number of days an infected person has and can spread the disease
  • -
  • $\gamma=1/D$: the proportion of infected recovering per day ( = 1/D)
  • -
-

the basic reproduction number $R_0$, is the total number of people an infected person infects. We just used an intuitive formula: -$$R_0 = \beta \cdot D\,.$$

-

Check $R_0$ for Colombia: https://github.com/restrepo/COVID-19/blob/master/covid.ipynb

- -
-
-
-
- -
- -
-
-

See Understanding the models that are used to model Coronavirus: Explaining the background and deriving the formulas of the SIR model from scratch. Coding and visualizing the model in Python.

-\begin{align} -\frac{d S}{d t}=&-\beta \cdot I \cdot \frac{S}{N} \\ -\frac{d I}{d t}=&\beta \cdot I \cdot \frac{S}{N}-\gamma \cdot I \\ -\frac{d R}{d t}=&\gamma \cdot I -\end{align} -
-
-
-
- -
- -
-
- -
-
-
def deriv(y, t, N=1000, β=1, γ=1/4):
-    S, I, R = y
-    dSdt = -β * S * I / N
-    dIdt = β * S * I / N - γ * I
-    dRdt = γ * I
-    return dSdt, dIdt, dRdt
-
- -
-
-
- -
-
- -
- -
-
-

We want start with an infected, $I_0=I(0)=1$ and a $R_0=R(0)=1.2$. -Then, by using $D=4$ -$$\beta=R_0/D=0.3\,.$$

- -
-
-
-
- -
- -
-
- -
-
-
N = 1000
-β = 0.32  # infected person infects 0.275 other person per day, such that R_0=1.2
-D = 4.0 # infections lasts four days
-γ = 1.0 / D
-
-S0, I0, R0 = 999, 1, 1.2  # initial conditions: one infected, rest susceptible
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
t = np.linspace(0, 199, 200) # Grid of time points (in days)
-y0 = [S0, I0, R0] # Initial conditions vector
-
-# Integrate the SIR equations over the time grid, t.
-ret = odeint(deriv, y0, t, args=(N, β, γ))
-S, I, R = ret.T
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
def plotsir(t, S, I, R,yscale='linear'):
-  f, ax = plt.subplots(1,1,figsize=(10,4))
-  ax.plot(t, S, 'b', alpha=0.7, linewidth=2, label='Susceptible')
-  ax.plot(t, I, 'y', alpha=0.7, linewidth=2, label='Infected')
-  ax.plot(t, R, 'g', alpha=0.7, linewidth=2, label='Recovered')
-  plt.yscale(yscale)
-  #plt.grid()
-  ax.set_xlabel('Time (days)')
-
-  ax.yaxis.set_tick_params(length=0)
-  ax.xaxis.set_tick_params(length=0)
-  #ax.grid(b=True, which='major', c='w', lw=2, ls='-')
-  legend = ax.legend()
-  legend.get_frame().set_alpha(0.5)
-  for spine in ('top', 'right', 'bottom', 'left'):
-      ax.spines[spine].set_visible(False)
-  plt.show();
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
plotsir(t, S, I, R,yscale='log')
-
- -
-
-
- -
-
- -
-
- - -
- - - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Scaling:

- -
-
-
-
- -
- -
-
- -
-
-
Nreal=50E6
-sc=Nreal/N
-sc
-
- -
-
-
- -
-
- -
-
- - - -
-
50000.0
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
'N0={:g}'.format(I0*sc)
-'Nmax={:g}'.format(18*sc)
-
- -
-
-
- -
-
- -
-
- - - -
-
'Nmax=900000'
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
S
-
- -
-
-
- -
-
- -
-
- - - -
-
array([999.        , 998.66897981, 998.31423138, 997.93410641,
-       997.52685001, 997.09059489, 996.62335562, 996.12302269,
-       995.58735649, 995.01398138, 994.40037971, 993.74388596,
-       993.04168115, 992.29078738, 991.48806285, 990.63019731,
-       989.71370811, 988.73493698, 987.69004784, 986.57502561,
-       985.38567616, 984.1176282 , 982.76633648, 981.32708715,
-       979.79500558, 978.16506631, 976.43210628, 974.59084096,
-       972.63588388, 970.56177017, 968.36298383, 966.0339893 ,
-       963.56926774, 960.96335768, 958.21090048, 955.3066907 ,
-       952.24573088, 949.02329103, 945.63497206, 942.07677315,
-       938.34516187, 934.43714656, 930.35035052, 926.0830852 ,
-       921.63442323, 917.00426863, 912.19342155, 907.20363893,
-       902.03768612, 896.69937882, 891.1936156 , 885.52639547,
-       879.70482288, 873.7370976 , 867.63248712, 861.40128456,
-       855.05474889, 848.60502949, 842.06507572, 835.4485329 ,
-       828.76962599, 822.04303349, 815.28375391, 808.50696744,
-       801.72789565, 794.96166199, 788.22315562, 781.52690148,
-       774.88693884, 768.31671044, 761.82896352, 755.43566464,
-       749.14792779, 742.97595932, 736.92901559, 731.01537636,
-       725.24233147, 719.61618079, 714.14224588, 708.82489264,
-       703.6675628 , 698.67281358, 693.84236364, 689.17714406,
-       684.67735303, 680.34251303, 676.17153006, 672.16275156,
-       668.31402556, 664.62275793, 661.08596736, 657.70033871,
-       654.46227327, 651.36793588, 648.41329915, 645.59418421,
-       642.90629801, 640.34526753, 637.90667046, 635.58606289,
-       633.37900391, 631.28107722, 629.28791023, 627.39519049,
-       625.59867971, 623.89422582, 622.2777729 , 620.74536928,
-       619.29317418, 617.9174628 , 616.6146298 , 615.38119242,
-       614.21379162, 613.10919302, 612.06428675, 611.07608661,
-       610.14172888, 609.25847031, 608.42368604, 607.63486685,
-       606.88961643, 606.18564825, 605.52078215, 604.89294111,
-       604.30014788, 603.74052121, 603.21227228, 602.71370133,
-       602.24319382, 601.79921721, 601.38031727, 600.98511483,
-       600.61230232, 600.26064064, 599.92895592, 599.61613654,
-       599.32113008, 599.04294053, 598.78062551, 598.53329361,
-       598.30010184, 598.0802532 , 597.87299433, 597.67761327,
-       597.49343728, 597.31983085, 597.15619372, 597.00195898,
-       596.85659136, 596.71958547, 596.59046425, 596.46877743,
-       596.35410002, 596.24603102, 596.14419204, 596.04822608,
-       595.95779637, 595.87258522, 595.79229299, 595.71663706,
-       595.64535091, 595.5781832 , 595.51489694, 595.45526866,
-       595.39908766, 595.3461553 , 595.29628431, 595.24929815,
-       595.2050304 , 595.1633242 , 595.12403167, 595.08701346,
-       595.05213821, 595.01928211, 594.98832849, 594.95916738,
-       594.93169517, 594.90581418, 594.88143239, 594.85846309,
-       594.83682455, 594.81643977, 594.79723619, 594.77914545,
-       594.76210312, 594.7460485 , 594.73092441, 594.71667696,
-       594.70325538, 594.69061183, 594.67870124, 594.66748115,
-       594.65691157, 594.64695479, 594.6375753 , 594.62873966,
-       594.62041635, 594.61257568, 594.60518966, 594.59823195])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
5E4,5*5E4
-
- -
-
-
- -
-
- -
-
- - - -
-
(50000.0, 250000.0)
-
- -
-
-
-
- -
-
- - - - -
- \ No newline at end of file diff --git a/_build/features/numba.html b/_build/features/numba.html deleted file mode 100644 index 625d531..0000000 --- a/_build/features/numba.html +++ /dev/null @@ -1,895 +0,0 @@ ---- -interact_link: content/features/numba.ipynb -kernel_name: python3 -kernel_path: content/features -has_widgets: false -title: |- - Optimization -pagenum: 8 -prev_page: - url: /features/algorithms-convergence.html -next_page: - url: /features/one-variable-equations.html -suffix: .ipynb -search: colab numba research google com example href github restrepo computationalmethods blob master material ipynb target parentimg src assets badge svg alt open compile numerical functions faster running problem integer summation precompile function jit complicated arrays - -comment: "***PROGRAMMATICALLY GENERATED, DO NOT EDIT. SEE ORIGINAL FILES IN /content***" ---- - -
-
Optimization
-
-
- -
-
-

Open In Colab

-

Numba

Compile numerical functions for faster running

- -
-
-
-
- -
- -
-
- -
-
-
import time
-import numpy as np
-from numba import jit
-import pandas as pd
-
- -
-
-
- -
-
- -
-
- -
-
----------------------------------------------------------------------------
-ImportError                               Traceback (most recent call last)
-<ipython-input-2-1194e744ea9c> in <module>()
-      1 import time
-      2 import numpy as np
-----> 3 from numba import jit
-      4 import pandas as pd
-
-ImportError: No module named 'numba'
-
-
-
-
-
- -
-
- -
- -
-
-

Example of the problem: integer summation

- -
-
-
-
- -
- -
-
- -
-
-
st=time.time()
-imax=10000
-for i in range(imax):
-    for j in range(imax):
-        a=i+j
-
-print(time.time()-st)
-
- -
-
-
- -
-
- -
-
- -
-
9.316529273986816
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
def suma(imax):
-    for i in range(imax):
-        for j in range(imax):
-            a=i+j
-    return a
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
st=time.time()
-a=suma(imax)
-print(time.time()-st)
-
- -
-
-
- -
-
- -
-
- -
-
4.799173831939697
-
-
-
-
-
-
- -
-
- -
- -
-
-

Precompile the function with @jit of numba

- -
-
-
-
- -
- -
-
- -
-
-
# jit decorator tells Numba to compile this function.
-# The argument types will be inferred by Numba when function is called.
-@jit
-def suma(imax):
-    for i in range(imax):
-        for j in range(imax):
-            a=i+j
-    return a
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
st=time.time()
-a=suma(imax)
-print(time.time()-st)
-
- -
-
-
- -
-
- -
-
- -
-
0.09396576881408691
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
a=pd.DataFrame()# []#0
-
- -
-
-
- -
-
- -
- -
-
-

A more complicated example with arrays

- -
-
-
-
- -
- -
-
- -
-
-
a=np.array( [0,0])
-np.concatenate((a,a))
-
- -
-
-
- -
-
- -
-
- - - -
-
array([0, 0, 0, 0])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
# jit decorator tells Numba to compile this function.
-# The argument types will be inferred by Numba when function is called.
-@jit#(nopython=True)
-def suma(imax,a):
-    for i in range(imax):
-        for j in range(imax):
-            a[i]=i+j
-    return(a)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
imax=10000
-s=time.time()
-a=np.zeros(imax)
-a=suma(imax,a)
-print(time.time()-s)        
-
- -
-
-
- -
-
- -
-
- -
-
0.00023245811462402344
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
s=time.time()
-a=np.zeros(imax)
-a=suma(imax,a)
-print(time.time()-s)        
-
- -
-
-
- -
-
- -
-
- -
-
0.0002434253692626953
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
s=time.time()
-a=np.zeros(imax)
-a=suma(imax,a)
-print(time.time()-s)        
-
- -
-
-
- -
-
- -
-
- -
-
0.0002474784851074219
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
>>> x = np.arange(-5, 5, 0.1)
->>> y = np.arange(-5, 5, 0.1)
->>> xx, yy = np.meshgrid(x, y, sparse=True)
->>> z = np.sin(xx**2 + yy**2) / (xx**2 + yy**2)
-#>>> h = plt.contourf(x,y,z)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
imax
-
- -
-
-
- -
-
- -
-
- - - -
-
10000
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
>>> x = np.arange(0, imax, 1)
->>> y = np.arange(0, imax, 1)
->>> xx, yy = np.meshgrid(x, y, sparse=False)
->>> z = xx+yy
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
xx
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[   0,    1,    2, ..., 9997, 9998, 9999],
-       [   0,    1,    2, ..., 9997, 9998, 9999],
-       [   0,    1,    2, ..., 9997, 9998, 9999],
-       ..., 
-       [   0,    1,    2, ..., 9997, 9998, 9999],
-       [   0,    1,    2, ..., 9997, 9998, 9999],
-       [   0,    1,    2, ..., 9997, 9998, 9999]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
from numba import jit
-import numpy as np
-
-@jit(nopython=True)
-def f(n):
-    #return np.array([ [ [x,y]  for x in range(n) ] for y in range(n) ])
-    for y in range(n):
-        return np.array([ (x,y)  for x in range(n) ] )
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
s=time.time()
-a=f(10000)
-print(time.time()-s)        
-
- -
-
-
- -
-
- -
-
- -
-
----------------------------------------------------------------------------
-NotImplementedError                       Traceback (most recent call last)
-<ipython-input-21-ad659232eeb3> in <module>()
-      1 s=time.time()
-----> 2 a=f(10000)
-      3 print(time.time()-s)
-
-/usr/local/lib/python3.5/dist-packages/numba/dispatcher.py in _compile_for_args(self, *args, **kws)
-    305                 argtypes.append(self.typeof_pyval(a))
-    306         try:
---> 307             return self.compile(tuple(argtypes))
-    308         except errors.TypingError as e:
-    309             # Intercept typing error that may be due to an argument
-
-/usr/local/lib/python3.5/dist-packages/numba/dispatcher.py in compile(self, sig)
-    577 
-    578                 self._cache_misses[sig] += 1
---> 579                 cres = self._compiler.compile(args, return_type)
-    580                 self.add_overload(cres)
-    581                 self._cache.save_overload(sig, cres)
-
-/usr/local/lib/python3.5/dist-packages/numba/dispatcher.py in compile(self, args, return_type)
-     78                                       impl,
-     79                                       args=args, return_type=return_type,
----> 80                                       flags=flags, locals=self.locals)
-     81         # Check typing error if object mode is used
-     82         if cres.typing_error is not None and not flags.enable_pyobject:
-
-/usr/local/lib/python3.5/dist-packages/numba/compiler.py in compile_extra(typingctx, targetctx, func, args, return_type, flags, locals, library)
-    777     pipeline = Pipeline(typingctx, targetctx, library,
-    778                         args, return_type, flags, locals)
---> 779     return pipeline.compile_extra(func)
-    780 
-    781 
-
-/usr/local/lib/python3.5/dist-packages/numba/compiler.py in compile_extra(self, func)
-    360         self.lifted = ()
-    361         self.lifted_from = None
---> 362         return self._compile_bytecode()
-    363 
-    364     def compile_ir(self, func_ir, lifted=(), lifted_from=None):
-
-/usr/local/lib/python3.5/dist-packages/numba/compiler.py in _compile_bytecode(self)
-    736         """
-    737         assert self.func_ir is None
---> 738         return self._compile_core()
-    739 
-    740     def _compile_ir(self):
-
-/usr/local/lib/python3.5/dist-packages/numba/compiler.py in _compile_core(self)
-    723 
-    724         pm.finalize()
---> 725         res = pm.run(self.status)
-    726         if res is not None:
-    727             # Early pipeline completion
-
-/usr/local/lib/python3.5/dist-packages/numba/compiler.py in run(self, status)
-    246                     # No more fallback pipelines?
-    247                     if is_final_pipeline:
---> 248                         raise patched_exception
-    249                     # Go to next fallback pipeline
-    250                     else:
-
-/usr/local/lib/python3.5/dist-packages/numba/compiler.py in run(self, status)
-    238                 try:
-    239                     event(stage_name)
---> 240                     stage()
-    241                 except _EarlyPipelineCompletion as e:
-    242                     return e.result
-
-/usr/local/lib/python3.5/dist-packages/numba/compiler.py in stage_nopython_backend(self)
-    656         """
-    657         lowerfn = self.backend_nopython_mode
---> 658         self._backend(lowerfn, objectmode=False)
-    659 
-    660     def stage_compile_interp_mode(self):
-
-/usr/local/lib/python3.5/dist-packages/numba/compiler.py in _backend(self, lowerfn, objectmode)
-    611             self.library.enable_object_caching()
-    612 
---> 613         lowered = lowerfn()
-    614         signature = typing.signature(self.return_type, *self.args)
-    615         self.cr = compile_result(typing_context=self.typingctx,
-
-/usr/local/lib/python3.5/dist-packages/numba/compiler.py in backend_nopython_mode(self)
-    598                 self.return_type,
-    599                 self.calltypes,
---> 600                 self.flags)
-    601 
-    602     def _backend(self, lowerfn, objectmode):
-
-/usr/local/lib/python3.5/dist-packages/numba/compiler.py in native_lowering_stage(targetctx, library, interp, typemap, restype, calltypes, flags)
-    898     lower.lower()
-    899     if not flags.no_cpython_wrapper:
---> 900         lower.create_cpython_wrapper(flags.release_gil)
-    901     env = lower.env
-    902     call_helper = lower.call_helper
-
-/usr/local/lib/python3.5/dist-packages/numba/lowering.py in create_cpython_wrapper(self, release_gil)
-    227         self.context.create_cpython_wrapper(self.library, self.fndesc,
-    228                                             self.env, self.call_helper,
---> 229                                             release_gil=release_gil)
-    230 
-    231     def setup_function(self, fndesc):
-
-/usr/local/lib/python3.5/dist-packages/numba/targets/cpu.py in create_cpython_wrapper(self, library, fndesc, env, call_helper, release_gil)
-    147                                 fndesc, env, call_helper=call_helper,
-    148                                 release_gil=release_gil)
---> 149         builder.build()
-    150         library.add_ir_module(wrapper_module)
-    151 
-
-/usr/local/lib/python3.5/dist-packages/numba/callwrapper.py in build(self)
-    120 
-    121         api = self.context.get_python_api(builder)
---> 122         self.build_wrapper(api, builder, closure, args, kws)
-    123 
-    124         return wrapper, api
-
-/usr/local/lib/python3.5/dist-packages/numba/callwrapper.py in build_wrapper(self, api, builder, closure, args, kws)
-    174 
-    175             retty = self._simplified_return_type()
---> 176             obj = api.from_native_return(retty, retval, env_manager)
-    177             builder.ret(obj)
-    178 
-
-/usr/local/lib/python3.5/dist-packages/numba/pythonapi.py in from_native_return(self, typ, val, env_manager)
-   1323                                                     "prevented the return of " \
-   1324                                                     "optional value"
--> 1325         out = self.from_native_value(typ, val, env_manager)
-   1326         return out
-   1327 
-
-/usr/local/lib/python3.5/dist-packages/numba/pythonapi.py in from_native_value(self, typ, val, env_manager)
-   1337 
-   1338         c = _BoxContext(self.context, self.builder, self, env_manager)
--> 1339         return impl(typ, val, c)
-   1340 
-   1341     def reflect_native_value(self, typ, val, env_manager=None):
-
-/usr/local/lib/python3.5/dist-packages/numba/targets/boxing.py in box_array(typ, val, c)
-    307     nativeary = nativearycls(c.context, c.builder, value=val)
-    308     if c.context.enable_nrt:
---> 309         np_dtype = numpy_support.as_dtype(typ.dtype)
-    310         dtypeptr = c.env_manager.read_const(c.env_manager.add_const(np_dtype))
-    311         # Steals NRT ref
-
-/usr/local/lib/python3.5/dist-packages/numba/numpy_support.py in as_dtype(nbtype)
-    134         return as_dtype(nbtype.dtype)
-    135     raise NotImplementedError("%r cannot be represented as a Numpy dtype"
---> 136                               % (nbtype,))
-    137 
-    138 
-
-NotImplementedError: Failed at nopython (nopython mode backend)
-(int64 x 2) cannot be represented as a Numpy dtype
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
a[[2]]
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[2, 0]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
a=(1,2)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
np.concatenate( (a,a))
-
- -
-
-
- -
-
- -
-
- - - -
-
array([1, 2, 1, 2])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
n_i=101
-n_i%10==0
-
- -
-
-
- -
-
- -
-
- - - -
-
False
-
- -
-
-
-
- -
-
- - - - -
- \ No newline at end of file diff --git a/_build/features/numerical-calculus-integration-methods.html b/_build/features/numerical-calculus-integration-methods.html deleted file mode 100644 index 30de6ff..0000000 --- a/_build/features/numerical-calculus-integration-methods.html +++ /dev/null @@ -1,1255 +0,0 @@ ---- -interact_link: content/features/numerical-calculus-integration-methods.ipynb -kernel_name: python3 -kernel_path: content/features -has_widgets: false -title: |- - Numerical integration methods -pagenum: 19 -prev_page: - url: /features/numerical-calculus-integration.html -next_page: - url: /features/linear-algebra.html -suffix: .ipynb -search: x f frac n b xi dx left right h s ab k function quadrature intab integration sum simpsons using where order interval given xk scipy composite l error formula e intervals trapezoidal rule points polynomial j previous intabf implementation int span epsilon methods lagrange interpolation integrate numerical cdots expression t adaptive ipynb integral next xn value not obtain obtained simple second activity precision colab com approximation p such approx prod begin end xj org style color red rules problem mu within dt step here approximate operatorname d m omegak applied omegai newton cotes low wikipedia png assume simpson method - -comment: "***PROGRAMMATICALLY GENERATED, DO NOT EDIT. SEE ORIGINAL FILES IN /content***" ---- - -
-
Numerical integration methods
-
-
- -
-
-

Integration for data points

Open In Colab

- -
-
-
-
- -
- -
-
-

Numerical approximation of integrals

-
-
-
-
- -
- -
-
-

The methods for numerical approximation that we will study here rely in the idea of approximate -$$\int_a^b f(x)\operatorname{d}x\,,$$ -by using some polinomial $p$, such that -$$\int_a^b f(x)\operatorname{d}x\approx \int_a^b P_n(x)\operatorname{d}x\,,$$ -The integral of a polynomial can be calculated analytically because we know its antiderivative.

-

Since, as we seen in Lagrange-Polynomial, the next polynomial of $n$th-degree -$$P_n(x) = \sum_{i=0}^n f(x_i)L_{n,i}(x) = \sum_{i=0}^n y_iL_{n,i}(x)\,,$$ -where -$$L_{n,i}(x) = \prod_{\begin{smallmatrix}m=0\\ m\neq i\end{smallmatrix}}^n \frac{x-x_m}{x_i-x_m} =\frac{(x-x_0)}{(x_i-x_0)}\frac{(x-x_1)}{(x_i-x_1)}\cdots \frac{(x-x_{i-1})}{(x_i-x_{i-1})}\underbrace{\frac{}{}}_{m\ne i} -\frac{(x-x_{i+1})}{(x_i-x_{i+1})} \cdots \frac{(x-x_{n-1})}{(x_i-x_{n-1})}\frac{(x-x_n)}{(x_i-x_n)} $$ -Given a well-behaved function $f(x)$, we have then

-$$f(x) \approx \sum_{k=0}^n f(x_k)L_{n,k}(x)$$\begin{align} -%$$ trick notebook cell -\int_a^b f(x)dx =& \int_a^b\sum_{k=0}^n f(x_k)L_{n,k}(x)dx \\ -=&\sum_{k=0}^n f(x_k) \int_a^b L_{n,k}(x)dx \\ -=&\sum_{k=0}^n f(x_k) \omega_k \, -%$$ -\end{align}

-where $\omega_k$ is a weight applied to each function value: -$$\omega_k = \int_a^b L_{n,k}(x) dx= \int_a^b\prod_{j=0,\ j\neq k}^{n}\frac{(x-x_j)}{(x_k-x_j)}dx$$ -Note that, since Lagrange polynomials do not depend on the function, we can calculate the weights $\omega_i$ using only the nodes $[x_0,x_1,\ldots x_n]$

- -
-
-
-
- -
- -
-
-

Error calculation

Including the error, the previous function $f(x)$ can be written as

-$$f(x) = \sum_{k=0}^n f(x_k)L_{n,k}(x) + \frac{(x-x_0)(x-x_1)\cdots(x-x_n)}{(n+1)!}f^{(n+1)}(\xi(x))$$

with $L_{n,k}(x)$ the lagrange basis functions. Integrating $f(x)$ over $[a,b]$, we obtain the next expression:

-$$\int_a^b f(x)dx = \int_a^b\sum_{k=0}^n f(x_k)L_{n,k}(x)dx + \int_a^b\frac{(x-x_0)(x-x_1)\cdots(x-x_n)}{(n+1)!}f^{(n+1)}(\xi(x))dx$$

It is worth mentioning this expression is a number, unlike differentiation where we obtained a function.

-

We can readily convert this expression in a weighted summation as

-$$\int_a^b f(x)dx = \sum_{k=0}^n \omega_i\,f(x_k) + \frac{1}{(n+1)!}\int_a^bf^{(n+1)}(\xi(x)) \prod_{k=0}^{n}(x-x_k)dx$$

Finally, the quadrature formula or Newton-Cotes formula is given by the next expression:

-$$\int_a^b f(x) dx = \sum \omega_i\, f(x_i) + E[f]$$

where the estimated error is

-$$E[f] = \frac{1}{(n+1)!}\int_a^bf^{(n+1)}(\xi(x)) \prod_{k=0}^{n}(x-x_k)dx $$

Asumming besides intervals equally spaced such that $x_i = x_0 + i\times h$, the error formula becomes:

-$$E[f] = \frac{h^{n+3}f^{n+2}(\xi)}{(n+1)!}\int_0^nt^2(t-1)\cdots(t-n) $$

if $n$ is even and

-$$E[f] = \frac{h^{n+2}f^{n+1}(\xi)}{(n+1)!}\int_0^nt(t-1)\cdots(t-n) $$

if $n$ is odd.

-

Below is a simple implementation of the quadrature formula or Newton-Cotes formula by using the implementation in scipy of the Interpolation polynomial in the Lagrangian form of order $n$ discussed in Interpolation from scipy interpolation

- -
-
-
-
- -
- -
-
- -
-
-
%pylab inline
-import numpy as np
-from scipy import interpolate
-import scipy.integrate as integrate
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
def F(Y,X):
-    '''
-    Antiderivate approximantion with Lagrange Polynomial 
-    '''
-    return interpolate.lagrange( X, Y ).integ()
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
def Quadrature(Y,X):
-    '''
-    Antiderivate approximantion with Lagrange Polynomial 
-    '''
-    antif=F(Y,X)
-    return antif(X[-1])-antif(X[0])
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
def PlotQuadrature( f, X, xmin, xmax, ymin, ymax, fig=None, leg=True ):
-    '''
-    Implementation of Newton-Cotes formula for A SINGLE INTERVAL
-    f: Function to integrate in A SINGLE INTERVAL
-    X: nodes of the Lagrangian interpolation polynomial
-    xmin,xmax,ymin, ymax: size of the figure
-    '''
-    Y = f( X )
-    
-    #X array
-    Xarray = np.linspace( xmin, xmax, 1000 )
-    #X area
-    Xarea = np.linspace( X[0], X[-1], 1000 )
-    #F array
-    Yarray = f( Xarray )
-    
-    #Lagrange polynomial
-    Ln = interpolate.lagrange( X, Y )
-    #Interpolated array
-    Parray = Ln( Xarray )
-    #Interpolated array for area
-    Parea = Ln( Xarea )
-    
-    #Plotting
-    if fig==None:
-        fig = plt.figure( figsize = (8,8) )
-    ax = fig.add_subplot(111)
-    #Function
-    ax.plot( Xarray, Yarray, linewidth = 3, color = "blue", label="$f(x)$" )
-    #Points
-    ax.plot( X, Y, "o", color="red", label="points", zorder = 10 )
-    #Interpolator
-    ax.plot( Xarray, Parray, linewidth = 2, color = "black", label="$P_{%d}(x)$"%(len(X)-1) )
-    #Area
-    ax.fill_between( Xarea, Parea, color="green", alpha=0.5 )
-    
-    #Format
-    ax.set_title( "%d-point Quadrature"%(len(X)), fontsize=16 )
-    ax.set_xlim( (xmin, xmax) )
-    ax.set_ylim( (0, 4) )
-    ax.set_xlabel( "$x$" )
-    ax.set_ylabel( "$y$" )
-    if leg:
-        ax.legend( loc="upper left", fontsize=16 )
-    ax.grid(1)
-    
-    return Quadrature(Y,X)
-
- -
-
-
- -
-
- -
- -
-
-

Trapezoidal rule

Using the previous formula, it is easily to derivate a set of low-order approximations for integration. Asumming a function $f(x)$ and an interval $[x_0,x_1]$, the associated quadrature formula is that obtained from a first-order Lagrange polynomial $P_1(x)$ given by:

-$$P_1(x) = \frac{(x-x_1)}{x_0-x_1}f(x_0) + \frac{(x-x_0)}{(x_1-x_0)}f(x_1)$$

Using this, it is readible to obtain the integrate:

-$$\int_{x_0}^{x_1}f(x)dx = \frac{h}{2}[ f(x_0) + f(x_1) ]-\frac{h^3}{12}f^{''}(\xi)$$

with $\xi \in [x_0, x_1]$ and $h = x_1-x_0$.

- -
-
-
-
- -
- -
-
-

Simple implementation

-
-
-
-
- -
- -
-
- -
-
-
#Function
-def f(x):
-    return 1+np.cos(x)**2+x
-
-#Quadrature with 2 points (Trapezoidal rule)
-a=-0.5
-b=1.5
-X = np.array([a,b])
-Q=PlotQuadrature( f, X, xmin=-1, xmax=2, ymin=0, ymax=4 )
-print('Full={}, trapezoid={}, rectangle={}'.format( integrate.quad(f,a,b)[0] ,  Quadrature(f(X),X), (b-a)*(f(b)+f(a))/2 ) )
-
- -
-
-
- -
-
- -
-
- -
-
Full=4.245647748216942, trapezoid=3.775154904633847, rectangle=3.7751549046338475
-
-
-
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
(b-a)*f(a),(b-a)*f(b)
-
- -
-
-
- -
-
- -
-
- - - -
-
(2.5403023058681398, 5.010007503399555)
-
- -
-
-
-
- -
-
- -
- - -
- -
- -
-
- -
-
-
integrate.trapz?
-
- -
-
-
- -
-
- -
-
- - - -
-
Signature: integrate.trapz(y, x=None, dx=1.0, axis=-1)
-Docstring:
-Integrate along the given axis using the composite trapezoidal rule.
-
-Integrate `y` (`x`) along given axis.
-
-Parameters
-----------
-y : array_like
-    Input array to integrate.
-x : array_like, optional
-    The sample points corresponding to the `y` values. If `x` is None,
-    the sample points are assumed to be evenly spaced `dx` apart. The
-    default is None.
-dx : scalar, optional
-    The spacing between sample points when `x` is None. The default is 1.
-axis : int, optional
-    The axis along which to integrate.
-
-Returns
--------
-trapz : float
-    Definite integral as approximated by trapezoidal rule.
-
-See Also
---------
-sum, cumsum
-
-Notes
------
-Image [2]_ illustrates trapezoidal rule -- y-axis locations of points
-will be taken from `y` array, by default x-axis distances between
-points will be 1.0, alternatively they can be provided with `x` array
-or with `dx` scalar.  Return value will be equal to combined area under
-the red lines.
-
-
-References
-----------
-.. [1] Wikipedia page: http://en.wikipedia.org/wiki/Trapezoidal_rule
-
-.. [2] Illustration image:
-       http://en.wikipedia.org/wiki/File:Composite_trapezoidal_rule_illustration.png
-
-Examples
---------
->>> np.trapz([1,2,3])
-4.0
->>> np.trapz([1,2,3], x=[4,6,8])
-8.0
->>> np.trapz([1,2,3], dx=2)
-8.0
->>> a = np.arange(6).reshape(2, 3)
->>> a
-array([[0, 1, 2],
-       [3, 4, 5]])
->>> np.trapz(a, axis=0)
-array([ 1.5,  2.5,  3.5])
->>> np.trapz(a, axis=1)
-array([ 2.,  8.])
-File:      /usr/local/lib/python3.5/dist-packages/numpy/lib/function_base.py
-Type:      function
-
-
- -
-
-
-
- -
-
- -
- -
-
-

In fact, as expected

- -
-
-
-
- -
- -
-
- -
-
-
Y=f(X)
-integrate.trapz(f(X),X)
-
- -
-
-
- -
-
- -
-
- - - -
-
3.7751549046338475
-
- -
-
-
-
- -
-
- -
- -
-
-

- -
-
-
-
- -
- -
-
-

For a better approximation we can use more intervals

- -
-
-
-
- -
- -
-
- -
-
-
x=np.linspace( X[0], X[-1], 1000 )
-integrate.trapz(f(x),x)
-
- -
-
-
- -
-
- -
-
- - - -
-
4.245647420030478
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
X[0]
-
- -
-
-
- -
-
- -
-
- - - -
-
-0.5
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
X[-1]
-
- -
-
-
- -
-
- -
-
- - - -
-
1.5
-
- -
-
-
-
- -
-
- -
- -
-
-

Simpson's rule

-
-
-
-
- -
- -
-
-

A slightly better approximation to integration is the Simpson's rule. For this, assume a function $f(x)$ and an interval $[x_0,x_2]$, with a intermediate point $x_1$. The associate second-order Lagrange polynomial is given by: See previous exercise

-$$P_2(x) = \frac{(x-x_1)(x-x_2)}{(x_0-x_1)(x_0-x_2)}f(x_0) + \frac{(x-x_0)(x-x_2)}{(x_1-x_0)(x_1-x_2)}f(x_1) + \frac{(x-x_0)(x-x_1)}{(x_2-x_0)(x_2-x_1)}f(x_2)$$

The final expression is then:

-$$\int_{x_0}^{x_2} f(x)dx = \frac{h}{3}[ f(x_0)+4f(x_1)+f(x_2) ]-\frac{h^5}{90}f^{(4)}(\xi)$$ -
-
-
-
- -
- -
-
- -
-
-
#Function
-def f(x):
-    return 1+np.cos(x)**2+x
-
-#Quadrature with 3 points (Simpson's rule)
-a=-0.5
-b=1.5
-x0=0.5
-X = np.array([a,x0,b])
-Q=PlotQuadrature( f, X, xmin=-1, xmax=2, ymin=0, ymax=4 )
-print('Full={}, P2={}, rectangle={}'.format( integrate.quad(f,a,b)[0] ,  Quadrature(f(X),X), (b-a)*(f(b)+f(a))/2 ) )
-
- -
-
-
- -
-
- -
-
- -
-
Full=4.245647748216942, P2=4.285253172123376, rectangle=3.7751549046338475
-
-
-
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Scipy implementation

Improves with number of points: -Simpons

- -
-
-
-
- -
- -
-
- -
-
-
integrate.simps?
-
- -
-
-
- -
-
- -
-
- - - -
-
Signature: integrate.simps(y, x=None, dx=1, axis=-1, even='avg')
-Docstring:
-Integrate y(x) using samples along the given axis and the composite
-Simpson's rule.  If x is None, spacing of dx is assumed.
-
-If there are an even number of samples, N, then there are an odd
-number of intervals (N-1), but Simpson's rule requires an even number
-of intervals.  The parameter 'even' controls how this is handled.
-
-Parameters
-----------
-y : array_like
-    Array to be integrated.
-x : array_like, optional
-    If given, the points at which `y` is sampled.
-dx : int, optional
-    Spacing of integration points along axis of `y`. Only used when
-    `x` is None. Default is 1.
-axis : int, optional
-    Axis along which to integrate. Default is the last axis.
-even : str {'avg', 'first', 'last'}, optional
-    'avg' : Average two results:1) use the first N-2 intervals with
-              a trapezoidal rule on the last interval and 2) use the last
-              N-2 intervals with a trapezoidal rule on the first interval.
-
-    'first' : Use Simpson's rule for the first N-2 intervals with
-            a trapezoidal rule on the last interval.
-
-    'last' : Use Simpson's rule for the last N-2 intervals with a
-           trapezoidal rule on the first interval.
-
-See Also
---------
-quad: adaptive quadrature using QUADPACK
-romberg: adaptive Romberg quadrature
-quadrature: adaptive Gaussian quadrature
-fixed_quad: fixed-order Gaussian quadrature
-dblquad: double integrals
-tplquad: triple integrals
-romb: integrators for sampled data
-cumtrapz: cumulative integration for sampled data
-ode: ODE integrators
-odeint: ODE integrators
-
-Notes
------
-For an odd number of samples that are equally spaced the result is
-exact if the function is a polynomial of order 3 or less.  If
-the samples are not equally spaced, then the result is exact only
-if the function is a polynomial of order 2 or less.
-File:      /usr/local/lib/python3.5/dist-packages/scipy/integrate/quadrature.py
-Type:      function
-
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
integrate.simps(f(X),X)
-
- -
-
-
- -
-
- -
-
- - - -
-
4.285253172123376
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
x=np.linspace( X[0], X[-1], 100000 )
-integrate.trapz(f(x),x),integrate.simps(f(x),x)
-
- -
-
-
- -
-
- -
-
- - - -
-
(4.245647748184187, 4.245647748216941)
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
4.245647748216942
-
- -
-
-
- -
-
- -
-
- - - -
-
4.245647748216942
-
- -
-
-
-
- -
-
- -
- -
-
-

Activity: Implement the Simpson method here or here by generalizing the previous Quadrature function to one that accepts lists of any size. Compares with the Scipy implementation for the next integral with a linspace of 100 points.

-

Hint: Note that the intervals for each 3 points can be obtained by slicing in steps of 2:

- -
-
-
-
- -
- -
-
- -
-
-
X=[1,2,3,4,5,6,7,8,9,10,11,12]
-i=0
-print(X[i:i+3])
-i=i+2
-print(X[i:i+3])
-i=i+2
-print(X[i:i+3])
-i=i+2
-print(X[i:i+3])
-
- -
-
-
- -
-
- -
-
- -
-
[1, 2, 3]
-[3, 4, 5]
-[5, 6, 7]
-[7, 8, 9]
-
-
-
-
-
-
- -
-
- -
- -
-
-

Activity

-
-
-
-
- -
- -
-
-
    -
  • Using the trapezoidal and the Simpson's rules, determine the value of the integral (4.24565)
  • -
-$$ \int_{-0.5}^{1.5}(1+\cos^2x + x)dx $$
    -
  • Take the previous routine Quadrature and the above function and explore high-order quadratures. What happends when you increase the number of points?
  • -
- -
-
-
-
- -
- -
-
-

N=20 -def f(x): - return 1+np.cos(x)**2+x

-

Quadrature with N points (Simpson's rule)

X = np.array(np.linspace(-0.5,1.5,N)) -Ln=Quadrature( f, X, xmin=-1, xmax=2, ymin=0, ymax=4 ) -integrate.simps(Ln(X),X) -print(poly1d(Ln))

- -
-
-
-
- -
- -
-
-

Activity

-
-
-
-
- -
- -
-
-

Approximate the following integrals using formulas Trapezoidal and Simpson rules. Are the accuracies of -the approximations consistent with the error formulas?

-\begin{eqnarray*} -&\int_{0}^{0.1}&\sqrt{1+ x}dx \\ -&\int_{0}^{\pi/2}&(\sin x)^2dx\\ -&\int_{1.1}^{1.5}&e^xdx -\end{eqnarray*} -
-
-
-
- -
- -
-
-

Composite Numerical Integration

-
-
-
-
- -
- -
-
-

Although above-described methods are good enough when we want to integrate along small intervals, larger intervals would require more sampling points, where the resulting Lagrange interpolant will be a high-order polynomial. These interpolant polynomials exihibit usually an oscillatory behaviour (best known as Runge's phenomenon), being more inaccurate as we increase $n$.

-

An elegant and computationally inexpensive solution to this problem is a piecewise approach, where low-order Newton-Cotes formula (like trapezoidal and Simpson's rules) are applied over subdivided intervals. This methods are already implemented in the previous scipy trapezoidal and Simpsons implementations. An internal implementation is given in the Appendix of integration, the Composite Trapezoidal rule given by:

-$$ \int_a^b f(x) dx = \frac{h}{2}\left[ f(a) + 2\sum_{j=1}^{N-1}f(x_j) + f(b) \right] - \frac{b-a}{12}h^2 f^{''}(\mu)$$

and the Composite Simpson's rule given by

-$$ \int_a^bf(x)dx = \frac{h}{3}\left[ f(a) +2 \sum_{j=1}^{(n/2)-1}f(x_{2j})+4\sum_{j=1}^{n/2}f(x_{2j-1})+f(b) \right] - \frac{b-a}{180}h^4f^{(4)}(\mu)$$ -
-
-
-
- -
- -
-
-

Composite trapezoidal rule

-
-
-
-
- -
- -
-
-

This formula is obtained when we subdivide the integration interval $[a,b]$ within sets of two points, such that we can apply the previous Trapezoidal rule to each one.

-

Let $f(x)$ be a well behaved function ($f\in C^2[a,b]$), defining the interval space as $h = (b-a)/N$, where N is the number of intervals we take, the Composite Trapezoidal rule is given by:

-$$ \int_a^b f(x) dx = \frac{h}{2}\left[ f(a) + 2\sum_{j=1}^{N-1}f(x_j) + f(b) \right] - \frac{b-a}{12}h^2 f^{''}(\mu)$$

for some value $\mu$ in $(a,b)$.

- -
-
-
-
- -
- -
-
-

Activity

-
-
-
-
- -
- -
-
-

Determine the value of the integral (4.24565)

-$$ \int_{-0.5}^{1.5}(1+\cos^2x + x)dx $$ -
-
-
-
- -
- -
-
-

Activity

-
-
-
-
- -
- -
-
-

An experiment has measured $dN(t)/dt$, the number of particles entering a counter, per unit time, as a function of time. Your problem is to integrate this spectrum to obtain the number of particles $N(1)$ that entered the counter -in the first second

-$$ N(1) = \int_0^1 \frac{dN}{dt} dt$$

For the problem it is assumed exponential decay so that there actually is an analytic answer.

-$$ \frac{dN}{dt} = e^{-t} $$

Compare the relative error for the composite trapezoid and Simpson rules. Try different values of N. Make a logarithmic plot of N vs Error.

- -
-
-
-
- -
- -
-
-
- -
-
-
-
- -
- -
-
-

Adaptive Quadrature Methods

-
-
-
-
- -
- -
-
-

Calculating the integrate of the function $f(x) = e^{-3x}\sin(4x)$ within the interval $[0,4]$, we obtain:

- -
-
-
-
- -
- -
-
- -
-
-
#Function
-def f(x):
-    return np.exp(-3*x)*np.sin(4*x)
-
-#Plotting
-X = np.linspace( 0, 4, 200 )
-Y = f(X)
-plt.figure( figsize=(14,7) )
-plt.plot( X, Y, color="blue", lw=3 )
-plt.fill_between( X, Y, color="blue", alpha=0.5 )
-plt.xlim( 0,4 )
-plt.grid()
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Using composite numerical integration is not completely adequate for this problem as the function exhibits different behaviours for differente intervals. For the interval $[0,2]$ the function varies noticeably, requiring a rather small integration interval $h$. However, for the interval $[2,4]$ variations are not considerable and low-order composite integration is enough. This lays a pathological situation where simple composite methods are not efficient. In order to remedy this, we introduce an adaptive quadrature methods, where the integration step $h$ can vary according to the interval. The main advantage of this is a controlable precision of the result.

- -
-
-
-
- -
- -
-
-

Simpson's adaptive quadrature

-
-
-
-
- -
- -
-
-

Although adaptive quadrature can be readily applied to any quadrature method, we illustrate the method with the Simpson's adaptive quadrature.

-

Let's assume a function $f(x)$. We want to compute the integral within the interval $[a,b]$. Using a simple Simpson's quadrature, we obtain:

-$$\int_a^bf(x)dx = S(a,b) - \frac{h^5}{90}f^{(4)}(\xi)$$

where we introduce the notation:

-$$S(a,b) = \frac{h}{3}\left[ f(a) + 4f(a+h) + f(b) \right]$$

and $h$ is simply $h = (b-a)/2$.

-

-

Now, instead of using an unique Simpson's quadrature, we implement two, by adding a new point in the midle of the interval $[a,b]$, $(a+b)/2$, yielding:

-$$\int_a^bf(x)dx = S\left(a,\frac{a+b}{2}\right) + S\left(\frac{a+b}{2},b\right) - \frac{1}{16}\left(\frac{h^5}{90}\right)f^{(4)}(\xi)$$

For this expression, we reasonably assume an equal fourth-order derivative $f^{(4)}(\xi) = f^{(4)}(\xi_1) = f^{(4)}(\xi_2) $, where $\xi_1$ is the estimative for the first subtinterval (i.e. $\xi_1\in[a,(a+b)/2]$), and $\xi_2$ for the second one (i.e. $\xi_1\in[(a+b)/2, b]$).

-

As both expressions can approximate the real value of the integrate, we can equal them, obtaining:

-$$ -\int_a^bf(x)dx \begin{cases} \sim S(a,b) - \frac{h^5}{90}f^{(4)}(\xi)\\ -\approx S\left(a,\frac{a+b}{2}\right) + S\left(\frac{a+b}{2},b\right) - \frac{1}{16}\left(\frac{h^5}{90}\right)f^{(4)}(\xi)\\ -\end{cases} -$$

which leads us to a simple way to estimate the error without knowing the fourth-order derivative, i.e.

-$$\frac{h^5}{90}f^{(4)}(\xi) = \frac{16}{15}\left| S(a,b) - S\left(a,\frac{a+b}{2}\right) - S\left(\frac{a+b}{2},b\right) \right|$$

If we fix a precision $\epsilon$, such that the obtained error for the second iteration is smaller

-$$\frac{1}{16}\frac{h^5}{90}f^{(4)}(\xi) < \epsilon $$

it implies:

-$$\left| S(a,b) - S\left(a,\frac{a+b}{2}\right) - S\left(\frac{a+b}{2},b\right) \right|< 15 \epsilon$$

and

-$$\left| \int_a^bf(x) dx- S\left(a,\frac{a+b}{2}\right) - S\left(\frac{a+b}{2},b\right) \right|< \epsilon$$

The second iteration is then $15$ times more precise than the first one.

- -
-
-
-
- -
- -
-
-

Steps Simpson's adaptive quadrature

-
-
-
-
- -
- -
-
-

1. Give the function $f(x)$ to be integrated, the inverval $[a,b]$ and set a desired precision $\epsilon$.

-

2. Compute the next Simpsons's quadratures:

-$$ S(a,b),\ S\left(a,\frac{a+b}{2}\right),\ S\left(\frac{a+b}{2},b\right) $$

3. If

-$$\frac{1}{15}\left| S(a,b) - S\left(a,\frac{a+b}{2}\right) - S\left(\frac{a+b}{2},b\right) \right|<\epsilon$$

then the integration is ready and is given by:

-$$\int_a^bf(x) dx \approx S\left(a,\frac{a+b}{2}\right) + S\left(\frac{a+b}{2},b\right) $$

within the given precision.

-

4. If the previous step is not fulfilled, repeat from step 2 using as new intervals $[a,(a+b)/2]$ and $[(a+b)/2,b]$ and a new precision $\epsilon_1 = \epsilon/2$. Repeating until step 3 is fulfilled for all the subintervals.

- -
-
-
-
- - - - -
- \ No newline at end of file diff --git a/_build/features/numerical-calculus-integration.html b/_build/features/numerical-calculus-integration.html deleted file mode 100644 index 6f43aea..0000000 --- a/_build/features/numerical-calculus-integration.html +++ /dev/null @@ -1,1374 +0,0 @@ ---- -interact_link: content/features/numerical-calculus-integration.ipynb -kernel_name: python3 -kernel_path: content/features -has_widgets: false -title: |- - Numerical integration -pagenum: 18 -prev_page: - url: /features/numerical-calculus-integration.html -next_page: - url: /features/numerical-calculus-integration-methods.html -suffix: .ipynb -search: x f numerical omega integration frac t universe simpsons singularity integral rule integrals g quadrature dx density equation calculus composite left endpoint function b int end using colab com next adaptive right begin span infty e methods improper where d r h z p trapezoidal infinite numpy align google only python given defined expression abstractions wikipedia intab previous operatorname pi value lambda research github svg cover used also functions programming org possible interval c terms xi mathbf implementation integrate style color red activity kappa infinity restrepo ipynb open ones shall since actual different found analytical approaches small such those differentiation - -comment: "***PROGRAMMATICALLY GENERATED, DO NOT EDIT. SEE ORIGINAL FILES IN /content***" ---- - -
-
Numerical integration
-
-
- -
-
-

Open In Colab

- -
-
-
-
- -
- -
-
-

Numerical Calculus. Integration

Open In Colab

- -
-
-
-
- -
- -
-
-

Throughout this section and the next ones, we shall cover the topic of numerical calculus. Calculus has been identified since ancient times as a powerful toolkit for analysing and handling geometrical problems. Since differential calculus was developed by Newton and Leibniz (in its actual notation), many different applications have been found, at the point that most of the current science is founded on it (e.g. differential and integral equations). Due to the ever increasing complexity of analytical expressions used in physics and astronomy, their usage becomes more and more impractical, and numerical approaches are more than necessary when one wants to go deeper. This issue has been identified since long ago and many numerical techniques have been developed. We shall cover only the most basic schemes, but also providing a basis for more formal approaches.

-

From 7 (Chapter 18)

-

We can only find anti-derivatives for a very small number of functions, such as those functions that are popular as problems in mathematics textbooks. Outside of math classes, these functions are rare

-
- -
-
-
-
- - - -
- - -
- -
- -
-
- -
-
-
%pylab inline
-import numpy as np
-import scipy.interpolate as interpolate
-import scipy.integrate as integrate
-
- -
-
-
- -
-
- -
-
- -
-
Populating the interactive namespace from numpy and matplotlib
-
-
-
-
-
-
- -
-
- -
- -
-
-

Numerical Integration

-
-
-
-
- -
- -
-
-

Integration is the second fundamental concept of calculus (along with differentiation). Numerical approaches are generally more useful here than in differentiation as the antiderivative procedure (analytically) is often much more complex, or even not possible. In this section we will cover some basic schemes, including numerical quadratures.

-

Geometrically, integration can be understood as the area below a funtion within a given interval. Formally, given a function $f(x)$ such that $f\in C^{1}[a,b]$, the antiderivative is defined as

-$$F(x) = \int f(x) dx$$

valid for all $x$ in $[a,b]$. However, a more useful expression is a definite integral, where the antiderivative is evaluated within some interval, i.e.

-$$F(b) - F(a) = \int_{a}^{b} f(x) dx$$

This procedure can be formally thought as a generalization of discrete weighted summation. This idea will be exploited below and will lead us to some first approximations to integration.

-

See pag. 66 of PDF

- -
-
-
-
- -
- -
-
-

Numpy abstractions

The programming paradigm with Numpy are the abstractions, where the algorithms are written in terms of operations with arrays, avoiding the use of programming loops. Low level operations between arrays are implemented in C/Fortran within Numpy. Therefore, a code with abstractions is automatically optimized.

-

Consider for example the numerical integration with the trapezoidal method

-

Credit Wikipedia [See Wikipedia](https://en.wikipedia.org/wiki/Numerical_integration#Methods_for_one-dimensional_integrals)

-

Wehere for each internval between $x_i$ and $x_{i+1}$, the average height of the function -$$\frac{f(x_i)+f(x_{i-1})}{2}\,,$$ -is used. Therefore -\begin{align*} - \int_a^b f(x)d x\approx \frac{1}{2}\sum_{i=1}^n (x_i-x_{i-1})(f(x_i)+f(x_{i-1}))\,. -\end{align*}

-

To implement the correspponding abstractions in Numpy it is convenient to define the following vectors -\begin{align*} - \Delta \mathbf{X}&=(x_1-x_0,x_2-x_1,\cdots,x_n-x_{n-1})\\ - \langle\mathbf{F}\rangle&=\frac{1}{2}(f(x_1)+f(x_0),f(x_2)+f(x_1),\cdots,f(x_n)+f(x_{n-1}))\,. -\end{align*} -The numerical approximation of the integral with the trapezoidal method is then just the dot product between the two previous vectors -\begin{align*} - \int_a^b f(x)d x\approx \Delta \mathbf{X}\cdot \langle\mathbf{F}\rangle -\end{align*}

-

We next present the code with different levels of abstractions. The faster is the first one with the direct implementation of the dot product.

- -
-
-
-
- -
- -
-
- -
-
-
def integracion (f,a,b,n=4,test=0):
-    '''Trapezoidal method for the numerical integration  de f entre a y b
-         con n intervalos
-    '''
-    import numpy as np
-    x=np.linspace(a,b,n+1)
-    y=f(x)
-    if test == 0:
-        return 0.5*np.dot((x[1:]-x[:-1]),(y[1:]+y[:-1]))
-    elif test ==1:
-        return 0.5*((x[1:]-x[:-1])*(y[1:]+y[:-1])).sum()
-
- -
-
-
- -
-
- -
- -
-
-

Implementation in scipy

-
-
-
-
- -
- -
-
-
integrate.quad(func,a,b,args=(),full_output=0,...)
-
-

Parameters: -python

-

See integrate.quad? for further details

- -
-
-
-
- -
- -
-
-

Usage example

-
-
-
-
- -
- -
-
- -
-
-
f= lambda x: np.sin ( x )/ x
-
- -
-
-
- -
-
- -
- -
-
-

Note that:

- -
-
-
-
- -
- -
-
- -
-
-
f(0)
-
- -
-
-
- -
-
- -
-
- -
-
/usr/local/lib/python3.5/dist-packages/ipykernel_launcher.py:1: RuntimeWarning: invalid value encountered in double_scalars
-  """Entry point for launching an IPython kernel.
-
-
-
-
-
-
- - - -
-
nan
-
- -
-
-
-
- -
-
- -
- -
-
-

Even so, the full tuple output with result and numerical error is obtained from

- -
-
-
-
- -
- -
-
- -
-
-
integrate.quad(f,0,1)
-
- -
-
-
- -
-
- -
-
- - - -
-
(0.9460830703671831, 1.0503632079297089e-14)
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
integrate.quad(f,0,1)[0]
-
- -
-
-
- -
-
- -
-
- - - -
-
0.9460830703671831
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
import time
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
s=time.time()
-print(integrate.quad(f,0,1))
-print(time.time()-s)
-
- -
-
-
- -
-
- -
-
- -
-
(0.9460830703671831, 1.0503632079297089e-14)
-0.00041174888610839844
-
-
-
-
-
-
- -
-
- -
- -
-
-

Force output to have only the result by asking for the entry 0 of the output tuple, note the [0] at the end:

- -
-
-
-
- -
- -
-
- -
-
-
integrate.quad(lambda x: np.sin ( x )/x,0,1)
-
- -
-
-
- -
-
- -
-
- - - -
-
(0.9460830703671831, 1.0503632079297089e-14)
-
- -
-
-
-
- -
-
- -
- -
-
-

Avoid singularities in custom solutions

- -
-
-
-
- -
- -
-
- -
-
-
integracion(lambda x: np.sin ( x )/x,1E-14,1,n=5)
-
- -
-
-
- -
-
- -
-
- - - -
-
0.9450787809533919
-
- -
-
-
-
- -
-
- -
- -
-
-

Sinintegrate: -$$\operatorname{Si}(t)=\int_0^t \frac{\sin x}{x}\, \operatorname{d}x$$

- -
-
-
-
- -
- -
-
- -
-
-
import numpy as np
-import scipy.integrate as integrate
-
-Sifloat=lambda t: integrate.quad(lambda x:np.sin(x)/x,0,t)[0]
-def Si(t):
-    try:
-        nn=np.array(t).shape[0]
-        f=np.vectorize(Sifloat)
-    except IndexError:
-        f=Sifloat
-    return f(t)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
Si(1)
-
- -
-
-
- -
-
- -
-
- - - -
-
0.9460830703671831
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
Si([1,2])
-
- -
-
-
- -
-
- -
-
- - - -
-
array([0.94608307, 1.60541298])
-
- -
-
-
-
- -
-
- -
- -
-
-

When you write LaTeX in  matplotlib, you must be sure that the backslash, '\', is properly interpreted as the key for LaTeX commands. This is accomplished by writting an r before the string declaration. Note the different behaviour of the backslash in the next two cells of code. In the first one \t is intepreted as the keyboard key <TAB> and \b as an empty space, while in the second, with the prefix r, it is just a pair of LaTeX commands

- -
-
-
-
- -
- -
-
- -
-
-
print('$\tan\beta$')
-
- -
-
-
- -
-
- -
-
- -
-
$	aeta$
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
print(r'$\tan\beta$')
-
- -
-
-
- -
-
- -
-
- -
-
$\tan\beta$
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
t=np.logspace(np.log10(1E-3),np.log10(2),200)
-tt=np.linspace(2,20,200)
-plt.semilogy(t,Si(t),'r-')
-plt.semilogy(tt,Si(tt),'b-')
-plt.xlabel('$t$',size=15)
-plt.ylabel(r'${\rm Si}(t)=\int_0^t {\sin\, x}/{x}\,{\rm d}\,x$',size=15)
-plt.grid()
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Activity

-
-
-
-
- -
- -
-
-

Models of Universe

From the Friedmann equations can be found the dynamics of the Universe, i.e., the evolution of the expansion with time that depends on the content of matter and energy of the Universe. Before introducing the general expression, there are several quatities that need to be defined.

-

It is convenient to express the density in terms of a critical density $\rho_c$ given by

-\begin{equation} -\rho_c = 3H_0^2/8\pi G -\end{equation}

where $H_o$ is the Hubble constant. The critical density is the density needed in order the Universe to be flat. To obtained it, it is neccesary to make the curvature of the universe $\kappa = 0$. The critical density is one value per -time and the geometry of the universe depends on this value, or equally on $\kappa$. For a universe with $\kappa<0$ it would ocurre a big crunch(closed universe) and for a $\kappa>0$ there would be an open universe.

-

Now, it can also be defined a density parameter, $\Omega$, a normalized density

-\begin{equation} -\Omega_{i,0} = \rho_{i,0}/\rho_{crit} -\end{equation}

where $\rho_{i,0}$ is the actual density($z=0$) for the component $i$. Then, it can be found the next expression

-\begin{equation} -\frac{H^2(t)}{H_{0}^{2}} = (1-\Omega_0)(1+z)^2 + \Omega_{m,0}(1+z^3)+ \Omega_{r,0}(1+z)^4 + \Omega_{\Lambda,0} -\end{equation}

where $\Omega_{m,0}$, $\Omega_{r,0}$ and $\Omega_{\Lambda,0}$ are the matter, radiation and vacuum density parameters. And $\Omega_0$ is the total density including the vacuum energy.

-

This expression can also be written in terms of the expansion or scale factor, $a$, by using:

-$$1+z = 1/a$$

For the next universe models, plot time($H_{0}^{-1}$ units) vs the scale factor:

-

-Einstein-de Sitter Universe: Flat space, null vacuum energy and dominated by matter

-\begin{equation} -t = H_0^{-1} \int_0^{a'} a^{1/2}da -\end{equation}

-Radiation dominated universe: All other components are not contributing

-$$ -t = H_0^{-1} \int_0^{a'} \frac{a}{[\Omega_{r,0}+a^2(1-\Omega_{r,0})]^{1/2}}da -$$

-WMAP9 Universe

-\begin{equation} -t = H_0^{-1} \int_0^{a'} \left[(1-\Omega_{0})+ \Omega_{M,0}a^{-1} + \Omega_{R,0}a^{-2} +\Omega_{\Lambda,0}a^2\right]^{-1/2} da -\end{equation}

You can take the cosmological parameters from the link

-

http://lambda.gsfc.nasa.gov/product/map/dr5/params/lcdm_wmap9.cfm or use these ones: $\Omega_M = 0.266$, -$\Omega_R = 8.24\times 10^{-5}$ and $\Omega_\Lambda = 0.734$.

-

Use composite Simpson's rule to integrate and compare it with the analytical expression in case you can get it. -The superior limit in the integral corresponds to the actual redshift $z=0$. What is happening to our universe?

- -
-
-
-
- -
- -
-
-

Activity

    -
  • Using the Simpson's adaptive quadrature determine the value of the next integral with a precision of float32.
  • -
-$$\int_0^4 e^{-3x}\sin(4x)dx$$

Activity

Fresnel integrals are commonly used in the study of light difraction at a rectangular aperture, they are given by:

-$$c(t) = \int_0^t\cos\left(\frac{\pi}{2}\omega^2\right)d\omega$$$$s(t) = \int_0^t\sin\left(\frac{\pi}{2}\omega^2\right)d\omega$$

These integrals cannot be solved using analitical methods. Using the previous routine for adaptive quadrature, compute the integrals with a precision of $\epsilon=10^{-4}$ for values of $t=0.1,0.2,0.3,\cdots 1.0$. Create two arrays with those values and then make a plot of $c(t)$ vs $s(t)$. The resulting figure is called Euler spiral, that is a member of a family of curves called Clothoid loops.

- -
-
-
-
- -
- -
-
-
- -
-
-
-
- -
- -
-
-

Improper Integrals

-
-
-
-
- -
- -
-
-

Improper integral can be processed with the quad function of scipy.integrate, or other integration functions, by using the infinity implementation of numpy, (which is the same of the math module, see below)

-
    -
  • Positive infinity ($+\infty$): np.inf and several aliases
  • -
  • Negagite infinity ($-\infty$): np.NINF -For details of the implementation and the aliases see here
  • -
- -
-
-
-
- -
- -
-
- -
-
-
import numpy as np
-
- -
-
-
- -
-
- -
- -
-
-

In Python the $\infty$ can be defined as

- -
-
-
-
- -
- -
-
- -
-
-
float('inf')
-
- -
-
-
- -
-
- -
-
- - - -
-
inf
-
- -
-
-
-
- -
-
- -
- -
-
-

It is already implemented in numpy

- -
-
-
-
- -
- -
-
- -
-
-
np.inf == float('inf')
-
- -
-
-
- -
-
- -
-
- - - -
-
True
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
24343555355567<np.inf
-
- -
-
-
- -
-
- -
-
- - - -
-
True
-
- -
-
-
-
- -
-
- -
- -
-
-

There are also function to check for infinity numbers:

- -
-
-
-
- -
- -
-
- -
-
-
np.isfinite(2)
-
- -
-
-
- -
-
- -
-
- - - -
-
True
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
np.isfinite(np.inf)
-
- -
-
-
- -
-
- -
-
- - - -
-
False
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
np.isfinite(2),np.isinf(np.inf)
-
- -
-
-
- -
-
- -
-
- - - -
-
(True, True)
-
- -
-
-
-
- -
-
- -
- -
-
-

So it is possible to evaluate improper integrals like

-$$ -\int_1^\infty x^{-2}\,\operatorname{d}x=1\,. -$$ -
-
-
-
- -
- -
-
- -
-
-
integrate.quad(lambda x: 1/x**2,1,np.inf)
-
- -
-
-
- -
-
- -
-
- - - -
-
(1.0, 1.1102230246251565e-14)
-
- -
-
-
-
- -
-
- -
- -
-
-

or -$$ -\int_{-\infty}^\infty \operatorname{e}^{x^{-2}}\,\operatorname{d}x=\sqrt{\pi},. -$$

- -
-
-
-
- -
- -
-
- -
-
-
integrate.quad(lambda x: np.exp(-x**2),np.NINF,np.inf)[0]==np.sqrt(np.pi)
-
- -
-
-
- -
-
- -
-
- - - -
-
True
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
integrate.quad(lambda x: np.exp(-x**2),0,np.inf)[0]==np.sqrt(np.pi)/2
-
- -
-
-
- -
-
- -
-
- - - -
-
True
-
- -
-
-
-
- -
-
- -
- -
-
-

Although the previous integration methods can be applied in almost every situation, improper integrals pose a challenger to numerical methods as they involve indeterminations and infinite intervals. Next, we shall cover some tricks to rewrite improper integrals in terms of simple ones. See for example here

- -
-
-
-
- -
- -
-
-

Left endpoint singularity

-
-
-
-
- -
- -
-
-

Assuming a function $f(x)$ such that it can be rewritten as

-$$ f(x) = \frac{g(x)}{(x-a)^p} $$

the integral over an interval $[a,b]$ converges only and only if $0<p<1$.

-

Using Simpson's composite rule, it is possible to compute the fourth-order Taylor polynomial of the function $g(x)$ at the point $a$, obtaining

-$$ P_4(x) = g(a) + g^{'}(a)(x-a)+\frac{g^{''}(a)}{2!}(x-a)^2 +\frac{g^{''}(a)}{3!}(x-a)^3+ \frac{g^{(4)}(a)}{4!}(x-a)^4$$

The integral can be then calculated as

-$$\int_a^b f(x)dx = \int_a^b\frac{g(x)-P_4(x)}{(x-a)^p}dx + \int_a^b\frac{P_4(x)}{(x-a)^p}dx$$

The second term is an integral of a polynimal, which can be easily integrated using analytical methods.

-

The first term is no longer pathologic as there is not any indetermination, and it can be determined using composite Simpson's rule

- -
-
-
-
- -
- -
-
-

Right endpoint singularity

-
-
-
-
- -
- -
-
-

This is the contrary case, where the indetermination is present in the extreme $b$ of the integration interval $[a,b]$. For this problem is enough to make a variable substitution

-$$ z=-x \ \ \ \ \ \ dz=-dx$$

With this, the right endpoint singularity becomes a left endpoint singularity and the previous method can be directly applied.

- -
-
-
-
- -
- -
-
-

Infinite singularity

-
-
-
-
- -
- -
-
-

Finally, infinite singularities are those where the integration domain is infinite, i.e.

-$$\int_a^\infty f(x)dx$$

this type of integrals can be easily turned into a left endpoint singularity jus making the next variable substitution

-$$t = x^{-1}\ \ \ \ \ dt = -x^{-2}dx$$

yielding

-$$ \int_a^\infty f(x)dx = \int_0^{1/a}t^{-2}f\left(\frac{1}{t}\right)dt $$ -
-
-
-
- -
- -
-
-

Activity

Error function is a special and non-elementary function that is widely used in probability, statistics and diffussion processes. -It is defined through the integral:

-$$\mbox{erf}(x) = \frac{2}{\sqrt{\pi}}\int_0^x e^{-t^2}dt$$

Using the substitution $u=t^2$ it is possible to use the previous methods for impropers integrals in order to evaluate the error function. Create a routine called ErrorFunction that, given a value of $x$, return the respective value of the integral.

- -
-
-
-
- -
- -
-
-
- -
-
-
-
- - - - - - -
- \ No newline at end of file diff --git a/_build/features/numerical-calculus.html b/_build/features/numerical-calculus.html deleted file mode 100644 index 0a398e3..0000000 --- a/_build/features/numerical-calculus.html +++ /dev/null @@ -1,2432 +0,0 @@ ---- -interact_link: content/features/numerical-calculus.ipynb -kernel_name: python3 -kernel_path: content/features -has_widgets: false -title: |- - Numerical calculus -pagenum: 16 -prev_page: - url: /features/least_action_minimization.html -next_page: - url: /features/numerical-calculus-integration.html -suffix: .ipynb -search: x f function xi frac n h derivative numerical point xih k float optional arguments formula formulas python check calculus points xj com used example endpoint mandatory colab midpoint d set where argument order using activity full tan github next b dx xk restrepo computationalmethods master ipynb e g scipy such c values br try implementation three except generic into error not list heat t left right beta cdots research google blob material src becomes j differentiation integration definition given expression previous derivate range need takes equation alpha l shall since its applications found only xh however very calculate taking - -comment: "***PROGRAMMATICALLY GENERATED, DO NOT EDIT. SEE ORIGINAL FILES IN /content***" ---- - -
-
Numerical calculus
-
-
- -
-
-

Open In Colab

- -
-
-
-
- -
- -
-
-

Numerical Calculus

Open In Colab

- -
-
-
-
- -
- -
-
-

Throughout this section and the next ones, we shall cover the topic of numerical calculus. Calculus has been identified since ancient times as a powerful toolkit for analysing and handling geometrical problems. Since differential calculus was developed by Newton and Leibniz (in its actual notation), many different applications have been found, at the point that most of the current science is founded on it (e.g. differential and integral equations). Due to the ever increasing complexity of analytical expressions used in physics and astronomy, their usage becomes more and more impractical, and numerical approaches are more than necessary when one wants to go deeper. This issue has been identified since long ago and many numerical techniques have been developed. We shall cover only the most basic schemes, but also providing a basis for more formal approaches.

-
-

* Class activities with CoCalc

Bibliography

- -
-
-
-
- - - -
- -
-
- -
-
-
%pylab inline
-import numpy as np
-import scipy.interpolate as interp
-
- -
-
-
- -
-
- -
- -
-
-
- -
-
-
-
- -
- -
-
-

Numerical Differentiation

-
-
-
-
- -
- -
-
-

According to the formal definition of differentiation, given a function $f(x)$ such that $f(x)\in C^1[a,b]$, the first order derivative is given by

-$$\frac{d}{dx}f(x) = f'(x) = \lim_{h\rightarrow 0} \frac{f(x+h)-f(x)}{h}$$

However, when $f(x)$ exhibits a complex form or is a numerical function (only a discrete set of points are known), this expression becomes unfeasible. In spite of this, this formula gives us a very first rough way to calculate numerical derivatives by taking a finite interval $h$, i.e.

-$$f'(x) \approx \frac{f(x+h)-f(x)}{h}$$

where the function must be known at least in $x_0$ and $x_1 = x_0+h$, and $h$ should be small enough.

- -
-
-
-
- -
- -
-
-

Example 1

-
-
-
-
- -
- -
-
-

Evaluate the first derivative of the next function using the previous numerical scheme at the point $x_0=2.0$ and using $h=0.5,\ 0.1,\ 0.05$

-

$f(x) = \sqrt{1+\cos^2(x)}$

-

Compare with the real function and plot the tangent line using the found values of the slope.

- -
-
-
-
- -
- -
-
- -
-
-
from scipy import misc
-
- -
-
-
- -
-
- -
- -
-
-

It is used as:

-
misc.derivative(func, x0, dx=1.0, n=1, args=(), order=3)
-
-

Parameters
-func : function → - Input function.
-x0 : float → - The point at which n-th derivative is found.
-dx : float, optional → - Spacing.
-n : int, optional → - Order of the derivative. Default is 1.
-args : tuple, optional → - Arguments
-order : int, optional → - Number of points to use, must be odd.

- -
-
-
-
- -
- -
-
- -
-
-
def function(x):
-    return np.sqrt( 1+np.cos(x)**2 )
-
-#X value
-x0 = 2
-xmin = 1.8
-xmax = 2.2
-
-x = np.linspace( xmin, xmax, 100 )
-
-plt.plot( x, np.sqrt( 1+np.cos(x)**2 ), color="black", label="function", linewidth=3, zorder=10 )
-
- -
-
-
- -
-
- -
-
- - - -
-
[<matplotlib.lines.Line2D at 0x7fdd94000e80>]
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Activity: We now check for the impact of the change of the spacing dx. Try from dx=0.5 and then small values

- -
-
-
-
- -
- -
-
- -
-
-
for i in range(5):
-    dx=eval(input('dx='))
-    print( misc.derivative(function,2,dx=dx) )
-
- -
-
-
- -
-
- -
-
- - -
-
-
-
- -
-
0.27884081567829266
-
-
-
-
-
-
- - -
-
-
-
- -
-
0.3462499420237386
-
-
-
-
-
-
- - -
-
-
-
- -
-
0.3493266965195363
-
-
-
-
-
-
- - -
-
-
-
- -
-
0.34935758881293744
-
-
-
-
-
-
- - -
-
-
-
- -
-
0.3493579009417047
-
-
-
-
-
-
- -
-
- -
- -
-
-

Compare with:

- -
-
-
-
- -
- -
-
- -
-
-
misc.derivative(function,2,dx=1E-12)
-
- -
-
-
- -
-
- -
-
- - - -
-
0.34927616354707425
-
- -
-
-
-
- -
-
- -
- -
-
-
- -
-
-
-
- -
- -
-
-

Implementation of the derivate of the function inside a full range

We now generalize the derivative function to allow the evaluation of the derivate in a full range of values. It will be designed such that the evaluation in just one point can be still possible. In this way, the new function can be used as a full replacement of derivative function.

-

To implement this function we need three keys ingredients of python:

-
    -
  1. try and except python progamming sctructure
  2. -
  3. Function definition with generic mandatory and optional arguments
  4. -
  5. Conversion of a float function into a vectorized fuction
  6. -
-

try and except python progamming sctructure

First we introduce the try and except python progamming sctructure, wich is used to bypass one python error. For example a zero dimension array has not a shape attribute, so that the following error, of type IndexError, is generated:

- -
-
-
-
- -
- -
-
- -
-
-
nn=np.array(3).shape[0]
-
- -
-
-
- -
-
- -
-
- -
-
----------------------------------------------------------------------------
-IndexError                                Traceback (most recent call last)
-<ipython-input-9-e1814928a8a6> in <module>
-----> 1 nn=np.array(3).shape[0]
-
-IndexError: tuple index out of range
-
-
-
-
-
- -
-
- -
- -
-
-

To bypass that error we use the following code:

- -
-
-
-
- -
- -
-
- -
-
-
try: 
-    nn=np.array(3).shape[0]
-except IndexError:
-    nn=-1
-
- -
-
-
- -
-
- -
- -
-
-

so that nn takes the values assigned in the except part:

- -
-
-
-
- -
- -
-
- -
-
-
nn
-
- -
-
-
- -
-
- -
-
- - - -
-
-1
-
- -
-
-
-
- -
-
- -
- -
-
-
- -
-
-
-
- -
- -
-
-

Activity: A float has the method is_integer() to check if the decimal part is zero. Creates a function is_integer(x) which works even in the case that the number is already an integer

- -
-
-
-
- -
- -
-
- -
-
-
x=2
-x.is_integer()
-
- -
-
-
- -
-
- -
-
- -
-
----------------------------------------------------------------------------
-AttributeError                            Traceback (most recent call last)
-<ipython-input-64-3027cbe30ddf> in <module>
-      1 x=2
-----> 2 x.is_integer()
-
-AttributeError: 'int' object has no attribute 'is_integer'
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
x=2.3
-x.is_integer()
-
- -
-
-
- -
-
- -
-
- - - -
-
False
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
type(2)==int
-
- -
-
-
- -
-
- -
-
- - - -
-
True
-
- -
-
-
-
- -
-
- -
- -
-
-

Objetos:

- -
str,int,float,list,dict
- -
-
-
-
- -
- -
-
- -
-
-
isinstance(2,list)
-
- -
-
-
- -
-
- -
-
- - - -
-
False
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
def is_integer(x):
-    # Returns true if x is integer
-    ....
-
- -
-
-
- -
-
- -
-
- -
-
-  File "<ipython-input-14-dd49574938f5>", line 3
-    ....
-        ^
-SyntaxError: invalid syntax
-
-
-
-
-
-
- -
-
- -
- -
-
-
- -
-
-
-
- -
- -
-
-

Function parameters

In python the function can be defined with mandatory and optional arguments

- -
-
-
-
- -
- -
-
- -
-
-
def f(a,b,c=2,d=3):
-    return a+b-c+d
-
- -
-
-
- -
-
- -
- -
-
-
    -
  • a,b: is like a tuple of mandatory arguments → (a,b)
  • -
  • c=2,d=3: is like a dictionary of optional arguments → {'c':2,'d':3}
  • -
- -
-
-
-
- -
- -
-
-

Function definition with generic mandatory and optional arguments

We need to introduce another important concept about functions. There is a powerfull way to define a function with generic arguments:

-
    -
  1. Instead of the mandatory arguments we can use the generic list pointer: *args
  2. -
  3. Instead of the optional arguments we can use the generic dictionary pointer: **kwargs
  4. -
- -
-
-
-
- -
- -
-
- -
-
-
def f(*args,**kwargs):
-    if args:
-        print('*args is the tuple of mandatory arguments: {}'.format(args))
-        print('This allows to have a dynamic return according to input:')
-        return type(args[0])
-    if kwargs:
-        print('*kwargs is the dictionary of optional arguments: {}'.format(kwargs))
-        print('This allows to have a dynamic return according to input:')
-        return type(list(kwargs.keys())[0]),type(list(kwargs.values())[0])
-
- -
-
-
- -
-
- -
- -
-
-
-

Activity; Check the function with any type of mandatory or optional argument

- -
-
-
-
- -
- -
-
-
    -
  • Check the function without arguments
  • -
- -
-
-
-
- -
- -
-
-
    -
  • Check the function with a mandatory argument
  • -
- -
-
-
-
- -
- -
-
-
    -
  • Check the function with several mandatory arguments
  • -
- -
-
-
-
- -
- -
-
-
    -
  • Check the function with several optional arguments
  • -
- -
-
-
-
- -
- -
-
- -
-
-
f(c=3)
-
- -
-
-
- -
-
- -
-
- -
-
*kwargs is the dictionary of optional arguments: {'c': 3}
-This allows to have a dynamic return according to input:
-
-
-
-
-
-
- -
-
----------------------------------------------------------------------------
-TypeError                                 Traceback (most recent call last)
-<ipython-input-75-8a4d05152912> in <module>
-----> 1 f(c=3)
-
-<ipython-input-71-72e15b8fe5b9> in f(*args, **kwargs)
-      7         print('*kwargs is the dictionary of optional arguments: {}'.format(kwargs))
-      8         print('This allows to have a dynamic return according to input:')
-----> 9         return type(kwargs.keys()[0]),type(kwargs.values()[0])
-
-TypeError: 'dict_keys' object does not support indexing
-
-
-
-
-
- -
-
- -
- -
-
-
    -
  • Check the function with one of the optional arguments equal to some list
  • -
- -
-
-
-
- -
- -
-
-
    -
  • Check the function with one string as mandatory argument, and with one of the optional arguments equal to some list
  • -
- -
-
-
-
- -
- -
-
-

Conversion of a float function into a vectorized function

An important numpy function is:

- -
-
-
-
- -
- -
-
-

Which convert a function which takes a float as an argument into a new function which que takes numpy arrays as an argument. The problem is that the converted function does not longer return a float when the argument is a float:

- -
-
-
-
- -
- -
-
-

It is used as:

-
np.vectorize(pyfunc,...)
-
-

Parameters: -pyfunc: A python function or method.

-

...

- -
-
-
-
- -
- -
-
- -
-
-
import math
-sinv=np.vectorize(math.sin)
-sinv([0.5,0.7])
-
- -
-
-
- -
-
- -
-
- - - -
-
array([0.47942554, 0.64421769])
-
- -
-
-
-
- -
-
- -
- -
-
-

Vectorization of Scipy method derivative

The problem is that derivative only works for one a point

- -
-
-
-
- -
- -
-
- -
-
-
misc.derivative(np.sin,1,dx=1E-6)
-
- -
-
-
- -
-
- -
-
- - - -
-
0.5403023058958567
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
misc.derivative(np.sin,[1,1.2],dx=1E-6)
-
- -
-
-
- -
-
- -
-
- -
-
----------------------------------------------------------------------------
-TypeError                                 Traceback (most recent call last)
-<ipython-input-13-287829b0db34> in <module>
-----> 1 misc.derivative(np.sin,[1,1.2],dx=1E-6)
-
-/usr/local/lib/python3.5/dist-packages/scipy/misc/common.py in derivative(func, x0, dx, n, args, order)
-    116     ho = order >> 1
-    117     for k in range(order):
---> 118         val += weights[k]*func(x0+(k-ho)*dx,*args)
-    119     return val / product((dx,)*n,axis=0)
-    120 
-
-TypeError: can only concatenate list (not "float") to list
-
-
-
-
-
- -
-
- -
- -
-
-

This is easily fixed with np.vectorize

- -
-
-
-
- -
- -
-
- -
-
-
array_derivate=np.vectorize(misc.derivative)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
array_derivate(np.sin,[1,1.2],dx=1E-6)
-
- -
-
-
- -
-
- -
-
- - - -
-
array([0.54030231, 0.36235775])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
array_derivate(np.sin,1,dx=1E-6)
-
- -
-
-
- -
-
- -
-
- - - -
-
array(0.54030231)
-
- -
-
-
-
- -
-
- -
- -
-
-

Code for the derivate of the function inside a full range

To recover the evaluation of a float into a float we can force the IndexError in order to use of the pure scipy derivative function when a float is given as input. The full implemention combine the three previos ingredients into a very compact pythonic-way function definition as shwon below

- -
-
-
-
- -
- -
-
- -
-
-
from scipy import misc
-def derivate(func,x0,**kwargs):
-    '''
-    Vectorized replacement of scipy.misc derivative:
-        from scipy.misc import derivative
-    For usage check the derivative help, e.g, in jupyter: 
-        from scipy.misc import derivative
-        derivative?
-    '''
-    try:
-        #x0: can be an array or a list  
-        nn=np.asarray(x0).shape[0] # force error if float is used 
-        fp=np.vectorize(misc.derivative)
-    except IndexError:
-        fp=misc.derivative
-        
-    return fp(func,x0,**kwargs)
-
- -
-
-
- -
-
- -
- -
-
-

which behaves exactly as the scipy derivative function when a float argument is used:

- -
-
-
-
- -
- -
-
- -
-
-
derivate(np.sin,1,dx=1E-6)
-
- -
-
-
- -
-
- -
-
- - - -
-
0.5403023058958567
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
derivate(np.sin,[1,2],dx=1E-6)
-
- -
-
-
- -
-
- -
-
- - - -
-
array([ 0.54030231, -0.41614684])
-
- -
-
-
-
- -
-
- -
- -
-
-

and as a vectorized function when an array argument is used:

- -
-
-
-
- -
- -
-
- -
-
-
misc.derivative(np.sin,1,dx=1E-6),misc.derivative(np.sin,2,dx=1E-6)
-
- -
-
-
- -
-
- -
-
- - - -
-
(0.5403023058958567, -0.41614683654600526)
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
derivate(np.sin,[1.,1.5],dx=1E-6,n=4,order=5)
-
- -
-
-
- -
-
- -
-
- - - -
-
array([-7.77156117e+08, -1.11022302e+09])
-
- -
-
-
-
- -
-
- -
- -
-
-

Let see now the implementation of the derivate function as full replacement of the derivative function:

- -
-
-
-
- -
- -
-
-

Test

Let us check the implementation with the previous function

- -
-
-
-
- -
- -
-
- -
-
-
func=lambda x: np.sqrt( 1+np.cos(x)**2 )
-
- -
-
-
- -
-
- -
- -
-
-

but now evaluated for a list of values

- -
-
-
-
- -
- -
-
- -
-
-
x=[1.8,2,2.2]
-funcp=derivate(func,x,dx=1E-3)
-funcp
-
- -
-
-
- -
-
- -
-
- - - -
-
array([0.21576117, 0.34935759, 0.41006125])
-
- -
-
-
-
- -
-
- -
- -
-
-

For the prevous X array:

- -
-
-
-
- -
- -
-
- -
-
-
x0 = 2
-xmin = 1.8
-xmax = 2.2
-
-x = np.linspace( xmin, xmax, 100 )
-
- -
-
-
- -
-
- -
- -
-
-

We have:

- -
-
-
-
- -
- -
-
- -
-
-
derivate(func,x,dx=1E-3).shape
-
- -
-
-
- -
-
- -
-
- - - -
-
(100,)
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
xmin = 1.8
-xmax = 2.2
-
-X = np.linspace( xmin, xmax, 100 )
-
-plt.plot( X, np.sqrt( 1+np.cos(X)**2 ), color="black", label="$f(x)$", linewidth=3)
-plt.plot( X, derivate(func,X,dx=1E-3), color="red", label="$f'(x)$", linewidth=3)
-plt.plot( X, derivate(func,X,dx=1E-3,n=2), color="blue", label="$f''(x)$", linewidth=3)
-plt.legend(loc='best',fontsize=15)
-plt.xlabel('$x$',size=15)
-plt.grid()
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Example

Finally we check the function $f(x)=\cos x$ in the range $[0,2\pi]$

- -
-
-
-
- -
- -
-
- -
-
-
xmin = 0
-xmax = 2*np.pi
-
-X = np.linspace( xmin, xmax, 100 )
-
-plt.plot( X, np.cos(X) , "g-", label="$f(x)=\cos x$", linewidth=3)
-plt.plot( X, derivate(lambda x:np.cos(x),X,dx=1E-3), color="red", label="$f'(x)$", linewidth=3)
-plt.plot( X, -np.sin(X) , 'b:', label="$-\sin x$", linewidth=3, zorder=10 )
-plt.plot( X, derivate(lambda x:np.cos(x),X,dx=1E-3,n=4,order=5), 'k:', label="$f^{(iv)}(x)$", linewidth=3)
-plt.legend(loc='best',fontsize=15)
-plt.xlabel('$x$',size=15)
-
- -
-
-
- -
-
- -
-
- - - -
-
Text(0.5,0,'$x$')
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
misc.derivative(np.cos,np.pi/2,n=4,dx=1E-3,order=5)
-
- -
-
-
- -
-
- -
-
- - - -
-
-1.3010426069826051e-06
-
- -
-
-
-
- -
-
- -
- -
-
-

Activity: Implement the full derivative function by using isinstance() instead of try and except

- -
-
-
-
- -
- -
-
- -
-
-
from scipy import misc
-
-def derivate(func,x0,**kwargs):
-    '''
-    Vectorized replacement of scipy.misc derivative:
-        from scipy.misc import derivative
-    For usage check the derivative help, e.g, in jupyter: 
-        from scipy.misc import derivative
-        derivative?
-    '''
-    if isinstance(x0,list):
-        print(x0)
-        fp=np.vectorize(misc.derivative)
-    else:
-        fp=misc.derivative
-    return fp(func,x0,**kwargs)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
type( np.array([2,3]) )
-
- -
-
-
- -
-
- -
-
- - - -
-
numpy.ndarray
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
isinstance( np.array([2,3]),numpy.ndarray )
-
- -
-
-
- -
-
- -
-
- - - -
-
True
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
derivate(np.cos,np.array([2,3]),dx=1E-6)
-
- -
-
-
- -
-
- -
-
- - - -
-
array([-0.90929743, -0.14112001])
-
- -
-
-
-
- -
-
- -
- -
-
-

Example: Heat transfer in a 1D bar

-
-
-
-
- -
- -
-
-

Fourier's Law of thermal conduction describes the diffusion of heat. Situations in which there are gradients of heat, a flux that tends to homogenise the temperature arises as a consequence of collisions of particles within a body. The Fourier's Law is giving by

-$$ q = -k\nabla T = -k\left( \frac{dT}{dx}\hat{i} + \frac{dT}{dy}\hat{j} + \frac{dT}{dz}\hat{k}\right)$$

where T is the temperature, $\nabla T$ its gradient and k is the material's conductivity. In the next example it is shown the magnitud of the heat flux in a 1D bar(wire).

- -
-
-
-
- -
- -
-
- -
-
-
def Temp(x):
-    return x**3 + 3*x-1
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
Xn = np.linspace(0,10,100)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
#Temperature profile 
-def Temp(x):
-    return x**3 + 3*x-1
-
-# Points where function is known
-Xn = np.linspace(0,10,100)
-
-plt.figure( figsize=(8,7) )
-plt.plot(Xn,derivate(Temp,Xn)*10)
-
-plt.grid()
-plt.xlabel( "$x$",fontsize =15 )
-plt.ylabel( r"$\frac{dT}{dx}$",fontsize =20 )
-plt.title( " Magnitud heat flux transfer in 1D bar" )
-
- -
-
-
- -
-
- -
-
- - - -
-
Text(0.5,1,' Magnitud heat flux transfer in 1D bar')
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Activity

-
-
-
-
- -
- -
-
-

Construct a density map of the magnitud of the heat flux of a 2D bar. Consider the temperature profile as -$$ T(x,y) = x^3 + 3x-1+y^2 $$

- -
-
-
-
- -
- -
-
-

Activity

The Poisson's equation relates the matter content of a body with the gravitational potential through the next equation

-$$\nabla^2 \phi = 4\pi G \rho$$$$\frac{1}{r^2}\frac{d}{dr}\left(r^2\frac{d\phi}{dr}\right)= 4\pi G \rho$$

where $\phi$ is the potential, $\rho$ the density and $G$ the gravitational constant.

-

Taking these data and using the three-point Midpoint formula, find the density field from the potential (seventh column in the file) and plot it against the radial coordinate. (Tip: Use $G=1$)

- -
-
-
-
- -
- -
-
-

Activity

-
-
-
-
- -
- -
-
-

The radar stations A and B, separated by the distance a = 500 m, track the plane -C by recording the angles $\alpha$ and $\beta$ at 1-second intervals. The successive readings are

-

- -
-
-
-
- -
- -
-
-

calculate the speed v using the 3 point approximantion at t = 10 ,12 and 14 s. Calculate the x component of the acceleration of the plane at = 12 s. The coordinates of the plane can be shown to be

-\begin{equation} -x = a\frac{\tan \beta}{\tan \beta- \tan \alpha}\\ -y = a\frac{\tan \alpha\tan \beta}{\tan \beta- \tan \alpha} -\end{equation}

- -
-
-
-
- -
- -
-
-
- -
-
-
-
- -
- - -
- -
- -
-
-

Appendix

-
-
-
-
- -
- -
-
-

One implementation of derivative algorithm

-
-
-
-
- -
- -
-
- -
-
-
#Function to evaluate
-def function(x):
-    return np.sqrt( 1+np.cos(x)**2 )
-
-#X value
-x0 = 2
-xmin = 1.8
-xmax = 2.2
-#h step
-hs = [0.5,0.1,0.05]
-
-#Calculating derivatives
-dfs = []
-for h in hs:
-    dfs.append( (function(x0+h)-function(x0))/h )
-    
-#Plotting
-plt.figure( figsize=(10,8) )
-#X array
-X = np.linspace( xmin, xmax, 100 )
-Y = function(X)
-plt.plot( X, Y, color="black", label="function", linewidth=3, zorder=10 )
-#Slopes
-Xslp = [1,x0,3]
-Yslp = [0,0,0]
-for df, h in zip(dfs, hs):
-    #First point
-    Yslp[0] = function(x0)+df*(Xslp[0]-Xslp[1])
-    #Second point
-    Yslp[1] = function(x0)
-    #Third point
-    Yslp[2] = function(x0)+df*(Xslp[2]-Xslp[1])
-    #Plotting this slope
-    plt.plot( Xslp, Yslp, linewidth = 2, label="slope$=%1.2f$ for $h=%1.2f$"%(df,h) )
-
-#Format
-plt.grid()
-plt.xlabel("x")
-plt.ylabel("y")
-plt.xlim( xmin, xmax )
-plt.ylim( 1, 1.15 )
-plt.legend( loc = "upper left" )
-
- -
-
-
- -
-
- -
-
- - - -
-
<matplotlib.legend.Legend at 0x7f2790fe7990>
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

n+1-point formula

-
-
-
-
- -
- -
-
-

A generalization of the previous formula is given by the (n+1)-point formula, where first-order derivatives are calculated using more than one point, what makes it a much better approximation for many problems. it is controled by the order option of the derivative function of scipy.misc

-

Theorem

-

For a function $f(x)$ such that $f(x)\in C^{n+1}[a,b]$, the next expression is always satisfied

-$$f(x) = P(x) + \frac{f^{(n+1)}(\xi(x))}{(n+1)!}(x-x_0)(x-x_1)\cdots(x-x_n)$$

where $\{x_i\}_i$ is a set of point where the function is mapped, $\xi(x)$ is some function of $x$ such that $\xi\in[a,b]$, and $P(x)$ is the associated Lagrange interpolant polynomial.

-

As $n$ becomes higher, the approximation should be better as the error term becomes neglectable.

- -
-
-
-
- -
- -
-
-

Taking the previous expression, and differenciating, we obtain

-$$f(x) = \sum_{k=0}^n f(x_k)L_{n,k}(x) + \frac{(x-x_0)(x-x_1)\cdots(x-x_n)}{(n+1)!}f^{(n+1)}(\xi(x))$$$$f'(x_j) = \sum_{k=0}^n f(x_k)L'_{n,k}(x_j) + \frac{f^{(n+1)}(\xi(x_j))}{(n+1)!} \prod_{k=0,k\neq j}^{n}(x_j-x_k)$$

where $L_{n,k}$ is the $k$-th Lagrange basis functions for $n$ points, $L'_{n,k}$ is its first derivative.

-

Note that the last expressions is evaluated in $x_j$ rather than a general $x$ value, the cause of this is because this expression is not longer valid for another value not within the set $\{x_i\}_i$, however this is not an inconvenient when handling real applications.

-

This formula constitutes the (n+1)-point approximation and it comprises a generalization of almost all the existing schemes to differentiate numerically. Next, we shall derive some very used formulas.

-

For example, the form that takes this derivative polynomial for 3 points $(x_i,y_i)$ is the following

-$$f'(x_j) = f(x_0)\left[ \frac{2x_j-x_1-x_2}{(x_0-x_1)(x_0-x_2)}\right] + -f(x_1)\left[ \frac{2x_j-x_0-x_2}{(x_1-x_0)(x_1-x_2)}\right] + -f(x_2)\left[ \frac{2x_j-x_0-x_1}{(x_2-x_0)(x_2-x_1)}\right] $$

-$$\hspace{2cm} + \frac{1}{6} f^{(3)}(\epsilon_j) \prod_{k=0,k\neq j}^{n}(x_j-x_k)$$

- -
-
-
-
- -
- -
-
-

Endpoint formulas

-
-
-
-
- -
- -
-
-

Endpoint formulas are based on evaluating the derivative at the first of a set of points, i.e., if we want to evaluate $f'(x)$ at $x_i$, we then need $(x_i$, $x_{i+1}=x_i+h$, $x_{i+2}=x_i+2h$, $\cdots)$. For the sake of simplicity, it is usually assumed that the set $\{x_i\}_i$ is equally spaced such that $x_k = x_0+k\cdot h$.

-

Three-point Endpoint Formula

-$$f'(x_i) = \frac{1}{2h}[-3f(x_i)+4f(x_i+h)-f(x_i+2h)] + \frac{h^2}{3}f^{(3)}(\xi)$$

with $\xi\in[x_i,x_i+2h]$

-

Five-point Endpoint Formula

-$$f'(x_i) = \frac{1}{12h}[-25f(x_i)+48f(x_i+h)-36f(x_i+2h)+16f(x_i+3h)-3f(x_i+4h)] + \frac{h^4}{5}f^{(5)}(\xi)$$

with $\xi\in[x_i,x_i+4h]$

-

Endpoint formulas are especially useful near to the end of a set of points, where no further points exist.

- -
-
-
-
- -
- -
-
-

Midpoint formulas

-
-
-
-
- -
- -
-
-

On the other hand, Midpoint formulas are based on evaluating the derivative at the middle of a set of points, i.e., if we want to evaluate $f'(x)$ at $x_i$, we then need $(\cdots$, $x_{i-2} = x_i - 2h$, $x_{i-1} = x_i - h$, $x_i$, $x_{i+1}=x_i+h$, $x_{i+2}=x_i+2h$, $\cdots)$.

-

Three-point Midpoint Formula

-$$f'(x_i) = \frac{1}{2h}[f(x_i+h)-f(x_i-h)] + \frac{h^2}{6}f^{(3)}(\xi)$$

with $\xi\in[x_i-h,x_i+h]$

-

Five-point Midpoint Formula

-$$f'(x_i) = \frac{1}{12h}[f(x_i-2h)-8f(x_i-h)+8f(x_i+h)-f(x_i+2h)] + \frac{h^4}{30}f^{(5)}(\xi)$$

with $\xi\in[x_i-2h,x_i+2h]$

-

As Midpoint formulas required one iteration less than Endpoint ones, they are more often used for numerical applications. Furthermore, the round-off error is smaller as well. However, near to the end of a set of points, they are no longer useful as no further points exists, and Endpoint formulas are preferable.

- -
-
-
-
- -
- -
-
-

Example with custom implementation

- -
-
-
-
- -
- -
-
- -
-
-
#Temperature profile 
-def Temp(x):
-    return x**3 + 3*x-1
-
-#Derivative three end point 
-
-def TEP( Yn,i, h=0.01,right=0 ):
-    suma = -3*Yn[i]+4*Yn[i+(-1)**right*1]-Yn[i+(-1)**right*2]
-    return suma/(2*h*(-1)**right)
-
-#Derivative mid point 
-def TMP( Ynh,Ynmh, h = 0.01 ):    
-    return (Ynh-Ynmh)/(2*h)
-
-# Points where function is known
-Xn = np.linspace(0,10,100)
-Tn = Temp(Xn)
-#Magnitude of heat flux array
-Q = np.zeros(len(Xn))
-#Left end derivative
-Q[0] = TEP(Tn,0)
-
-#Mid point derivatives
-index = len(Xn)-1
-for i in xrange( 1,index ):    
-    Q[i] =  TMP( Tn[i+1],Tn[i-1] )
-
-#Right end derivative      
-Q[-1] = TEP( Tn,index,right=1 ) 
-
-#Plotting 
-plt.figure( figsize=(8,7) )
-plt.plot(Xn,Q)
-
-plt.grid()
-plt.xlabel( "x",fontsize =15 )
-plt.ylabel( "$\\frac{dT}{dx}$",fontsize =20 )
-plt.title( " Magnitud heat flux transfer in 1D bar" )
-
- -
-
-
- -
-
- -
-
- - - -
-
<matplotlib.text.Text at 0x7f87263de3d0>
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- - - - -
- \ No newline at end of file diff --git a/_build/features/one-variable-equations-fixed-point.html b/_build/features/one-variable-equations-fixed-point.html deleted file mode 100644 index 2ba3ac7..0000000 --- a/_build/features/one-variable-equations-fixed-point.html +++ /dev/null @@ -1,37359 +0,0 @@ ---- -interact_link: content/features/one-variable-equations-fixed-point.ipynb -kernel_name: python3 -kernel_path: content/features -has_widgets: false -title: |- - Fixed point -pagenum: 10 -prev_page: - url: /features/one-variable-equations.html -next_page: - url: /features/interpolation.html -suffix: .ipynb -search: p f x n method function frac point fixed root stop g steps example iteration pi pn com convergence xi fp newton planet bisection solution using condition raphson mass m restrepo computationalmethods master material variable equations where epsilon colab activity nm e distance next step equation derivation raw end very rho image google svg secant methods not give line githubusercontent roots radius c r approx light alpha vec github numerical guest img given optimize obtain oplus derivative routine theta research ipynb sm d enough interval algorithm straight sanitize true satisfied repeat functions cos conditions same between last relative problem scipy - -comment: "***PROGRAMMATICALLY GENERATED, DO NOT EDIT. SEE ORIGINAL FILES IN /content***" ---- - -
-
Fixed point
-
-
- -
-
-

Open In Colab

- -
-
-
-
- -
- -
-
-

One Variable Equations. Part II

Open In Colab

- -
-
-
-
- - - -
- -
-
- -
-
-
%pylab inline
-
- -
-
-
- -
-
- -
-
- -
-
Populating the interactive namespace from numpy and matplotlib
-
-
-
-
-
-
- -
-
/usr/local/lib/python3.7/dist-packages/IPython/core/magics/pylab.py:160: UserWarning: pylab import has clobbered these variables: ['rc', 'f']
-`%matplotlib` prevents importing * from pylab and numpy
-  "\n`%matplotlib` prevents importing * from pylab and numpy"
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
from matplotlib import animation, rc
-rc('animation', html='jshtml')
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
import numpy as np
-from scipy import integrate
-from scipy import optimize
-
- -
-
-
- -
-
- -
- -
-
-

Fixed-point Iteration

-
-
-
-
- -
- -
-
-

Although in many cases the use of Bisection is more than enough, there are some pathological situations where the use of more advanced methods is required. -One of the advantages featured by this method is one does not have to give an interval where the solution is within, instead, from a seed the algorithm will converge towards the required solution.

- -
-
-
-
- -
- -
-
-

Steps FP

-
-
-
-
- -
- -
-
-
    -
  1. Take your function $f(x)$ and rewrite it like -$$g(x) = x - f(x)\,.$$
  2. -
-

In this way, find the root of $f(x_0)$ is equivalent to find the value when -$$g(x_0)=x_0\,.$$ -This $x_0$ is called the fixed-point of $g(x)$. Note that $g(x)|_{f=0}=x$ is just and straight line of slope one and zero intercept. Therefore, the fixed points corresponds to the points where $g(x)$ crosses that straight line.

-
    -
  1. Give a guest to the solution (root of $f(x)$). This value would be the seed $p_0$, and correspond to the point: $(p_0,g(p_0))$ -IMG
  2. -
  3. Check the distance to the straight line by goint to the point: $(p_0,g(p_0))$ -IMG
  4. -
  5. Go to the point on the straight line: $p_1 = g(p_0)$ → $(g(p_0),g(p_0))$ -IMG
  6. -
  7. The next guest to the solution will be given by $p_1$ → $(p_1,g(p_1))$. -IMG
  8. -
  9. Compare $p_1$ with $g(p_1)$: If the stop condition is not satisfied, then repeat step 2 but now with $p_1$.
  10. -
  11. The End!
  12. -
- -
-
-
-
- -
- -
-
-

Example: Find the roots of the next function:

-$$f(x) = \frac{x^2-1}{3}\,.$$

We define

-

Step 1:

- -
-
-
-
- -
- -
-
- -
-
-
def f(x):
-    return (x**2-1)/3.0
-
-g = lambda x: x-f(x)
-
- -
-
-
- -
-
- -
- -
-
-

Step 2:

- -
-
-
-
- -
- -
-
- -
-
-
p0 = 0.1
-(px,py)=(p0,g(p0))
-(px,py)
-
- -
-
-
- -
-
- -
-
- - - -
-
(0.1, 0.43000000000000005)
-
- -
-
-
-
- -
-
- -
- -
-
-

- -
-
-
-
- -
- -
-
-

Step 3:

- -
-
-
-
- -
- -
-
- -
-
-
(px,py)=(g(p0), g(p0) )
-(px,py)
-
- -
-
-
- -
-
- -
-
- - - -
-
(0.43000000000000005, 0.43000000000000005)
-
- -
-
-
-
- -
-
- -
- -
-
-

Step 4: Suggest a solution:

- -
-
-
-
- -
- -
-
- -
-
-
p1=g(p0)
-(px,py)=(p1, g(p1) )
-(px,py)
-
- -
-
-
- -
-
- -
-
- - - -
-
(0.43000000000000005, 0.7017)
-
- -
-
-
-
- -
-
- -
- -
-
-

- -
-
-
-
- -
- -
-
-

Step 5: Since $p_1$ is still quite differente from $g(p_1)$ we need to continue with another iteration

- -
-
-
-
- -
- -
-
-

Implementation of algorithm

- -
-
-
-
- -
- -
-
- -
-
-
#Defining Fixed-point iteration function
-def FixedPoint_Animation( f, pini, Nmax, xmin, xmax ):
-    g = lambda x: x-f(x)
-    #Initial condition
-    pi = [pini,]
-    px = [pini,pini,]
-    py = [0,]
-    #Iterations
-    for n in range(Nmax+3):
-        pi.append( g(pi[n]) )
-        px.append( g(pi[n]) )
-        px.append( g(pi[n]) )
-        py.append( g(pi[n]) )
-        py.append( g(pi[n]) )
-    
-    py.append( g(pi[n+1]) )
-    pi = np.array( pi )
-    px = np.array( px )
-    py = np.array( py )
-    
-    print ("Result:", pi[-1])
-    
-    #Array X-axis
-    X = np.linspace(xmin,xmax,100)
-    
-    #Initializing Figure
-    fig = plt.figure( figsize=(7,7) )
-    ax = fig.add_subplot(111)
-    #Graphic iterations
-    fixedpoint, = ax.plot( [], [], color="red", linewidth = 3 )
-    #Function g
-    ax.plot( X, g(X), color="green", linewidth = 2 )
-    #Identity funcion
-    ax.plot( X, X, color="blue", linewidth = 2 )
-    ax.grid(True)
-    ax.set_xlim( (xmin, xmax) )
-    ax.set_ylim( (xmin, xmax) )
-    ax.set_xlabel( "X axis" )
-    ax.set_ylabel( "Y axis" )
-    ax.set_title( "Fixed-Point iteration" )
-        
-    def init():
-        fixedpoint.set_data([], [])
-        return fixedpoint,
-    
-    def animate(i):
-        #Setting new data
-        fixedpoint.set_data( px[:2*i], py[:2*i] )
-        ax.set_title( "Fixed-Point. Iteration %d"%i )
-        return fixedpoint,
-    
-    return animation.FuncAnimation(fig, animate, init_func=init,frames=Nmax, interval=500, blit=True)
-
- -
-
-
- -
-
- -
- -
-
-

Find the roots of the next functions:

-$$f_1(x) = \frac{x^2-1}{3}$$

using Fixed-Point iteration.

- -
-
-
-
- -
- -
-
- -
-
-
def f1(x):
-    return (x**2-1)/3.0
-
-FixedPoint_Animation( f1, pini = 0.1, Nmax = 15, xmin = 0, xmax = 1.2 )
-
- -
-
-
- -
-
- -
-
- -
-
Result: 0.9999999890733635
-
-
-
-
-
-
- - -
- - - - - - -
- -
- -
- - - - - - - - - -
-
- - - - - - -
-
-
- - - - -
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Ejemplo 3: -$$f_2(x) = x-\cos x$$

- -
-
-
-
- -
- -
-
- -
-
-
def f2(x):
-    return x-np.cos(x)
-
-FixedPoint_Animation( f2, pini = 0.1, Nmax = 15, xmin = 0, xmax = 1.2 )
-
- -
-
-
- -
-
- -
-
- -
-
Result: 0.7387663516682054
-
-
-
-
-
-
- - -
- - - - - - -
- -
- -
- - - - - - - - - -
-
- - - - - - -
-
-
- - - - -
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
def g(x):
-    return x-f1(x)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
from scipy import optimize
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
help(optimize.fixed_point)
-
- -
-
-
- -
-
- -
-
- -
-
Help on function fixed_point in module scipy.optimize.minpack:
-
-fixed_point(func, x0, args=(), xtol=1e-08, maxiter=500, method='del2')
-    Find a fixed point of the function.
-    
-    Given a function of one or more variables and a starting point, find a
-    fixed point of the function: i.e., where ``func(x0) == x0``.
-    
-    Parameters
-    ----------
-    func : function
-        Function to evaluate.
-    x0 : array_like
-        Fixed point of function.
-    args : tuple, optional
-        Extra arguments to `func`.
-    xtol : float, optional
-        Convergence tolerance, defaults to 1e-08.
-    maxiter : int, optional
-        Maximum number of iterations, defaults to 500.
-    method : {"del2", "iteration"}, optional
-        Method of finding the fixed-point, defaults to "del2",
-        which uses Steffensen's Method with Aitken's ``Del^2``
-        convergence acceleration [1]_. The "iteration" method simply iterates
-        the function until convergence is detected, without attempting to
-        accelerate the convergence.
-    
-    References
-    ----------
-    .. [1] Burden, Faires, "Numerical Analysis", 5th edition, pg. 80
-    
-    Examples
-    --------
-    >>> from scipy import optimize
-    >>> def func(x, c1, c2):
-    ...    return np.sqrt(c1/(x+c2))
-    >>> c1 = np.array([10,12.])
-    >>> c2 = np.array([3, 5.])
-    >>> optimize.fixed_point(func, [1.2, 1.3], args=(c1,c2))
-    array([ 1.4920333 ,  1.37228132])
-
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
def f1(x):
-    return (x**2-1)/3.0
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
optimize.fixed_point(lambda x: x-f1(x),0.1)
-
- -
-
-
- -
-
- -
-
- - - -
-
array(1.)
-
- -
-
-
-
- -
-
- -
- -
-
-

g(x)=x-f(x)=x_0 -g(x_0)=x_0-f(x_0)=x_0

- -
-
-
-
- -
- -
-
- -
-
-
f1(1)
-
- -
-
-
- -
-
- -
-
- - - -
-
0.0
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
g(1),1-f1(1)
-
- -
-
-
- -
-
- -
-
- - - -
-
(1.0, 1.0)
-
- -
-
-
-
- -
-
- -
- -
-
-

Stop conditions FP

-
-
-
-
- -
- -
-
-

The stop conditions are the same than Bisection:

-
    -
  • A fixed distance between the last two steps (absolute convergence):

    -

    $$|p_i - p_{i-1}|<\epsilon$$

    -
  • -
  • A fixed relative distance between the last two steps (relative convergence):

    -

    $$\frac{|p_i - p_{i-1}|}{|p_i|}<\epsilon\ \ \ \ \ p_i \neq 0$$

    -
  • -
  • Function tolerance:

    -

    $$f(p_i)< \epsilon$$

    -
  • -
  • Computational stop:

    -

    If $N>N_{max}$, stop!

    -
  • -
- -
-
-
-
- -
- -
-
- -
-
-
import random
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
random.randint(1,4)
-
- -
-
-
- -
-
- -
- -
-
-

Activity: Use the optimize.fixed_point to find the root of f2(x)

- -
-
-
-
- -
- -
-
-

Example 4

-
-
-
-
- -
- -
-
-

There is a type of functions whose roots coincides with a local or global minima or maxima. This condition implies the function does not cross the x-axis at the root and the problem cannot be solved by using Bisection as the criterion of different signs cannot be satisfied. Fixed-point iteration is a more feasible alternative when solving these problems.

-

As an example, here we shall solve the roots of the function

-

$f(x) = x^2\cos(2x)$

-

For this, we plot the function first:

- -
-
-
-
- -
- -
-
-

It is clear there are three root within the plotted interval, i.e. $x_0 = -\pi/4$, $x_1 = 0$ and $x_2 = \pi/4$. Using bisection for the first and third roots we obtain:

- -
-
-
-
- -
- -
-
- -
-
-
def f(x):
-    return x**2*np.cos(2*x)
-
-X = np.linspace(-1,1,100)
-plt.plot( X, f(X), lw=2 )
-plt.xlabel("X axis")
-plt.xlabel("Y axis")
-plt.grid(True)
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
print( "Root x_1", optimize.bisect( f, a=-1, b=-0.5) )
-print( "Root x_2", optimize.bisect( f, a=0.5, b=1) )
-
- -
-
-
- -
-
- -
-
- -
-
Root x_1 -0.7853981633979856
-Root x_2 0.7853981633979856
-
-
-
-
-
-
- -
-
- -
- -
-
-

However, when applying bisection to the middle root, we obtain:

- -
-
-
-
- -
- -
-
- -
-
-
print( "Root x_0", optimize.bisect( f, a=-0.5, b=0.5) )
-
- -
-
-
- -
-
- -
-
- -
-
----------------------------------------------------------------------------
-ValueError                                Traceback (most recent call last)
-<ipython-input-33-76a08fa07ea3> in <module>
-----> 1 print( "Root x_0", optimize.bisect( f, a=-0.5, b=0.5) )
-
-/usr/local/lib/python3.7/dist-packages/scipy/optimize/zeros.py in bisect(f, a, b, args, xtol, rtol, maxiter, full_output, disp)
-    547     if rtol < _rtol:
-    548         raise ValueError("rtol too small (%g < %g)" % (rtol, _rtol))
---> 549     r = _zeros._bisect(f, a, b, xtol, rtol, maxiter, args, full_output, disp)
-    550     return results_c(full_output, r)
-    551 
-
-ValueError: f(a) and f(b) must have different signs
-
-
-
-
-
- -
-
- -
- -
-
-

Now, applying Fixed-point iteration:

- -
-
-
-
- -
- -
-
- -
-
-
FixedPoint_Animation( f, pini = 0.4, Nmax = 50, xmin = -0.5, xmax = 0.5 )
-
- -
-
-
- -
-
- -
-
- -
-
Result: 0.017317568681637058
-
-
-
-
-
-
- - -
- - - - - - -
- -
- -
- - - - - - - - - -
-
- - - - - - -
-
-
- - - - -
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Activity: Comprobar con scipy y fixed_point

- -
-
-
-
- -
- -
-
-

ACTIVITY FP

-
-
-
-
- -
- -
-
-

When a new planet is discovered, there are different methods to estimate its physical properties. Many times is only possible to estimate either the planet mass or the planet radius and the other property has to be predicted through computer modelling.

-

If one has the planet mass, a very rough way to estimate its radius is to assume certain composition (mean density) and a homogeneous distribution (a very bad assumption!). For example, for the planet Gliese 832c with a mass $M= 5.40 M_{\oplus}$, if we assume an earth-like composition, i.e. $\bar \rho_{\oplus} = 5520\ kg/m^3$, we obtain:

-$$R_{g832c} = \left( \frac{3 M_{g832c}}{ 4 \pi \bar\rho_{\oplus} } \right)^{1/3} \approx 1.75 R_{\oplus}$$

That would be the planet radius if the composition where exactly equal to earth's.

-

A more realistic approach is assuming an internal one-layer density profile like:

-$$\rho(r) = \rho_0 \exp\left( -\frac{r}{L} \right)$$

where $\rho_0$ is the density at planet centre and $L$ is a characteristic lenght depending on the composition. From numerical models of planet interiors, the estimated parameters for a planet of are $M= 5.40 M_{\oplus}$ are approximately $\rho_0 = 18000\ kg/m^3$ and $L = 6500\ km$.

-

Integrating over the planet volume, we obtain the total mass as

-$$M = 4\pi \int_0^R \rho(r)r^2dr$$

This is a function of the mass in terms of the planet radius.

-

Solving the equation $M(R) = M_{g832c}$ it would be possible to find a more realistic planet radius. However when using numerical models, it is not possible to approach the solution from the left side as a negative mass makes no sense.

- -
-
-
-
- -
- -
-
-

-In an IPython notebook, solve the previous problem and find the radius of **Gliese 832c** using your own version of the Fixed-point iteration algorithm. -

- -
-
-
-
- -
- -
-
-
- -
-
-
-
- -
- -
-
-

Newton-Raphson Method

-
-
-
-
- -
- -
-
-

Although Fixed-point iteration is an efficient algorithm as compared with Bisection, the Newton-Raphson method is an acceletared convergent scheme where the roots of a function are easily found with just a few iterations.

- -
-
-
-
- -
- -
-
-

Derivation NM

-
-
-
-
- -
- -
-
-

Although this method can be presented from an algorithmic point of view, the mathematical deduction is very useful as it allows us to understand the essence of the approximation as well as estimating easily the convergence errors.

-

Let be $f(x)$ a continuous and differentiable function defined within an interval $[a,b]$ (i.e. $f\in \mathcal{C}^2[a,b]$), and $p$ is a root of the function such that $f(p) = 0$. If we give an initial an enough close guess $p_0$ to this root, such that $|p-p_0|<\epsilon$, where $\epsilon$ is adequately small, we can expand the function by using a second order taylor serie, yielding:

-$$f(p) = f(p_0) + (p-p_0)f'(p_0) + \frac{(p-p_0)^2}{2}f''(p_0) + \mathcal{O}^3(|p-p_0|)$$

but as $f(p) = 0$ and $|p-p_0|^2<\epsilon^2$ is an even smaller quantity, we can readily neglect from second order terms, obtaining

-$$p \approx p_0 - \frac{f(p_0)}{f'(p_0)} \equiv p_1$$

If we repeat this process but now using $p_1$ as our guess to the root instead of $p_0$ we shall obtain:

-$$p \approx p_1 - \frac{f(p_1)}{f'(p_1)} \equiv p_2$$

and so...

-$$p \approx p_n - \frac{f(p_n)}{f'(p_n)} \equiv p_{n+1}$$

where each new iteration is a better approximation to the real root.

- -
-
-
-
- -
- -
-
-

Steps NM

-
-
-
-
- -
- -
-
-
    -
  1. Take your function $f(x)$ and derive it, $f'(x)$.
  2. -
  3. Give a guest to the solution (root of $f(x)$). This value would be the seed $p_0$.
  4. -
  5. The next guest to the solution will be given by

    -

    $$p_{n+1} = p_n - \frac{f(p_n)}{f'(p_{n})}$$

    -
  6. -
  7. If the stop condition is not satisfied, then repeat step 3.

    -
  8. -
  9. The End!
  10. -
- -
-
-
-
- -
- -
-
- -
-
-
#Defining Newton Method
-def NewtonRaphson_Animation( f, fp, pini, Nmax, xmin, xmax ):
-    #Initial condition
-    p = [pini,]
-    p_dash = []
-    p_der = []
-    #Iterations
-    for n in range(Nmax):
-        p.append( p[n] - f(p[n])/fp(p[n]) )
-        p_dash.append( p[n] )
-        p_dash.append( p[n] )
-        p_der.append( 0 )
-        p_der.append( f(p[n]) )
-    
-    p = np.array( p )
-    p_dash = np.array( p_dash )
-    p_der = np.array( p_der )
-    
-    print (  "Result:", p[-1])    
-    #Array X-axis
-    X = np.linspace(xmin,xmax,100)
-    
-    #Initializing Figure
-    fig = plt.figure( figsize=(7,7) )
-    ax = fig.add_subplot(111)
-    #Graphic iterations
-    dash, = ax.plot( [], [], "--", color="gray", linewidth = 2 )
-    derivative, = ax.plot( [], [], color="red", linewidth = 3 )
-    #Function f
-    ax.plot( X, f(X), color="green", linewidth = 2 )
-    #Horizontal line
-    ax.hlines( 0, xmin,xmax, color="black", lw = 2 )
-    ax.grid(True)
-    ax.set_xlim( (xmin, xmax) )
-    ax.set_xlabel( "X axis" )
-    ax.set_ylabel( "Y axis" )
-    ax.set_title( "Fixed-Point iteration" )
-        
-    def init():
-        dash.set_data([], [])
-        derivative.set_data([], [])
-        return dash, derivative
-    
-    def animate(i):
-        #Setting new data
-        dash.set_data( p_dash[:2*i+2], p_der[:2*i+2] )
-        derivative.set_data( p_dash[2*i+1:2*i+3], p_der[2*i+1:2*i+3] )
-        ax.set_title( "Newthon-Raphson Method. Iteration %d"%i )
-        return dash, derivative
-    
-    return animation.FuncAnimation(fig, animate, init_func=init,frames=Nmax, interval=500, blit=True)
-
- -
-
-
- -
-
- -
- -
-
-

Example 5

-
-
-
-
- -
- -
-
-

Find one root of the function:

-

$f(x) = x^2 - x$

-

with derivative

-

$f'(x) = 2x -1$

-

using the Newton-Raphson method.

- -
-
-
-
- -
- -
-
- -
-
-
#Defining the function
-def f(x): 
-    return x**2-x
-#Defining the derivative
-def df(x): 
-    return 2*x-1
-#Calculating root
-NewtonRaphson_Animation( f, df, pini = 0.55, Nmax = 10, xmin = 0, xmax = 3.5 )
-
- -
-
-
- -
-
- -
-
- -
-
Result: 1.0
-
-
-
-
-
-
- - -
- - - - - - -
- -
- -
- - - - - - - - - -
-
- - - - - - -
-
-
- - - - -
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Stop conditions NM

-
-
-
-
- -
- -
-
-

The stop conditions are the same than Bisection and Fixed-point iteration:

-
    -
  • A fixed distance between the last two steps (absolute convergence):

    -

    $$|p_i - p_{i-1}|<\epsilon$$

    -
  • -
  • A fixed relative distance between the last two steps (relative convergence):

    -

    $$\frac{|p_i - p_{i-1}|}{|p_i|}<\epsilon\ \ \ \ \ p_i \neq 0$$

    -
  • -
  • Function tolerance:

    -

    $$f(p_i)< \epsilon$$

    -
  • -
  • Computational stop:

    -

    If $N>N_{max}$, stop!

    -
  • -
- -
-
-
-
- -
- -
-
-

Convergence NM

-
-
-
-
- -
- -
-
-

It is possible to demonstrate by means of the previous derivation procedure, that the convergence of the Newton-Raphson method is quadratic, i.e., if $p$ is the exact root and $p_n$ is the $n$-th iteration, then

-$$|p_{n+1}-p|\leq C |p_n-p|^2$$

for a fixed ans positive constant $C$.

-

This implies, if the initial guess is good enough such that |p_0-p| is small, the convergence is achieved very fast as each iteration improves the precision twice in the order of magnitude, e.g., if $|p_0-p|\sim 10^{-1}$, $|p_1-p|\sim 10^{-2}$, $|p_2-p|\sim 10^{-4}$, $|p_2-p|\sim 10^{-8}$ and so.

- -
-
-
-
- -
- -
-
- -
-
-
#Defining Newton Method
-def NewtonRaphson( f, fp, pini, Nmax ):
-    #Initial condition
-    p = pini
-    #Iterations
-    for n in  range(Nmax):
-        p = p - f(p)/fp(p)
-    #Final result
-    return p
-
- -
-
-
- -
-
- -
- -
-
-

ACTIVITY

-

In an IPython notebook, copy the latter routine NewtonRaphson and the Bisection routine provided in this notebook (and if you have it already, the Fixed-point iteration routine as well) and find the root of the next function using all the methods.

-

$f(x) = x - \cos(x)$

-

Plot in the same figure the convergence of each method as a function of the number of iterations.

- -
-
-
-
- -
- -
-
-

See the Summary section at the end for the implementation in Scipy

- -
-
-
-
- -
- -
-
-
- -
-
-
-
- -
- -
-
-

Secant Method

-
-
-
-
- -
- -
-
-

The Newton-Raphson method is highly efficient as the convergence is accelerated, however there is a weakness with it: one needs to know the derivative of the function beforehand. This aspect may be complicated when dealing with numerical functions or even very complicated analytical functions. Numerical methods to derive the input function can be applied, but this extra procedure may involve an extra computing time that compensates the time spent by using other methods like Bisection.

- -
-
-
-
- -
- -
-
-

Derivation SM

-
-
-
-
- -
- -
-
-

Retaking the iterative expression obtained from the Newton-Raphson method:

-$$p_{n+1} = p_n - \frac{f(p_n)}{f'(p_{n})}\,,$$

or, changing $n \to n-1$

-$$p_{n} = p_{n-1} - \frac{f(p_{n-1})}{f'(p_{n-1})}\,.$$

The derivative can be approximated as

-$$f'(p_n) = \lim_{p_{n}\rightarrow p_{n-1}} \frac{f(p_{n})-f(p_{n-1})}{p_{n}-p_{n-1}} $$

As we know, the convergence of the NR method is quadratic, so $p_{n-1}$ should be close enough to $p_n$ such that one can assume $p_{n-1}\rightarrow p_n$ and the previous term is:

-$$f'(p_n) \approx \frac{f(p_{n})-f(p_{n-1})}{p_{n}-p_{n-1}} $$

or, changing $n \to n-1$

-$$f'(p_{n-1}) \approx \frac{f(p_{n-1})-f(p_{n-2})}{p_{n-1}-p_{n-2}} $$

The final expression for the $n$-th iteration of the root is then:

-$$p_{n} = p_{n-1} - \frac{f(p_{n-1})}{f'(p_{n-1})}\,.$$$$p_n = p_{n-1} - \frac{ f(p_{n-1})(p_{n-1}-p_{n-2}) }{f(p_{n-1})-f(p_{n-2})}$$

In this consists the Secant method, what is just an approximation to the Newton-Raphson method, but without the derivative term.

- -
-
-
-
- -
- -
-
-

Steps SM

-
-
-
-
- -
- -
-
-
    -
  1. Give the input function $f(x)$.
  2. -
  3. Give two guests to the solution (root of $f(x)$). These values would be the seeds $p_0$, $p_1$.
  4. -
  5. The next guest to the solution will be given by

    -

    $$p_n = p_{n-1} - \frac{ f(p_{n-1})(p_{n-1}-p_{n-2}) }{f(p_{n-1})-f(p_{n-2})}$$

    -
  6. -
  7. If the stop condition is not satisfied, then repeat step 3.

    -
  8. -
  9. The End!
  10. -
- -
-
-
-
- -
- -
-
-

See the Summary section at the end for the implementation in Scipy

- -
-
-
-
- -
- -
-
-

ACTIVITY

-

In an IPython notebook and based on the routine NewtonRaphson, write your own routine SecantMethod that performs the previous steps for the Secant Method. Test your code with the function $f(x)$:

-

$f(x) = x - \cos(x)$ -</font>

- -
-
-
-
- -
- -
-
-

ACTIVITY

-

It is known that light rays are deflected when they pass near by a gravitational field and that this deviation is proportional to the body mass which the light is interacting with and inversely proportional to the passing distance. -Since it is common finding very massive structures in the universe and the measures that are done to study it involve photons, it makes sense to study what happens to a light source image when the rays get close to a grumpy object like a dark matter halo.

-

In order to study the light deflection in these cases, it will be used the simplest model, gravitational lens theory, where the len is a very massive object. A sketch of a typical system is shown in the figure below. The source plane is the light source or image that is going to be affected, $\eta$ is the distance from a image point to the line of sight and $\beta$ the subtended angle by the point. -The lens plane corresponds to the mass that affects the light coming from the source, $\xi$ is the new image point distance to the line of sight, $\theta$ is the subtended angle by the new point position. Then, $\alpha$ is the deflection angle.

-

Since from observations $\theta$ is known, the problem to be solved per pixel usually is

-\begin{equation} -\beta = \theta - \hat{\alpha}(\theta) -\end{equation}

but $\alpha$ also depends on $\theta$ besides the len halo properties. This would allow construct the real image -from the distorted and magnified one.

-

-

This equation can also be written in terms of distances

-\begin{equation} -\vec{\eta} = \frac{D_s}{D_d} \vec{\xi} - D_{ds}\alpha ( \vec{\xi }) -\end{equation}

The solution to the lens equation is easier to get if it is assumed that the len is axially symmetric. In this case, the deflection angle takes the next form

-$$ \hat{\alpha}(\vec{\xi}) = \frac{\vec{\xi}}{|\vec{\xi}|^2} \frac{8G\pi}{c^2} \int_0^\xi d\xi'\xi'\Sigma(\xi')$$

The quantity $\Sigma$ is the surface mass density, i.e., the len's mass enclosed inside $\xi$ circle per area unit.
-It is important to notice that the direction of $\alpha$ is the same as $\xi$ and consequently $\eta$.

-

The problem to be solved is the next: Given the positions of a square find the image distorsion due to gravitational lensing, i.e., find the root of \xi in the trascendal equation it satisfies. Use the routines given below and all of -the data for the len and image that is going to be distorted.

- -
-
-
-
- -
- -
-
- -
-
-
#Superficial density of the lens
-def Sup_density(radio):
-    return radio*M*len(r[r<radio])/radio**2.
-
-#Deviation angle due to the gravitational len
-def des_angle( radio ):
-    return 2*np.pi*4*G*integrate.quad( Sup_density ,0, radio )[0]/(radio*c**2)
-
-#Len equation
-def Len_equation(radio, eta):
-    return eta - Ds*radio/Dd - Dds*des_angle( radio )
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
# Len distribution generated 
-M = 3e7
-L = 1e5
-puntos = 6
-Ds = 1000
-Dd = 900
-Dds = Ds - Dd
-G = 4.302e-3# pc M_sun**-1(km/s)**2
-c = 3e6 # km/s 
-x = np.linspace(0,L,puntos)
-y = np.linspace(0,L,puntos)
-X,Y = np.meshgrid(x,y)
-#Generating meshgrid of points 
-X = np.reshape(X,puntos*puntos)
-Y = np.reshape(Y,puntos*puntos)
-r = np.sqrt(X**2 + Y**2)
-
-#Image to be distorted
-Li = 5
-ni = 8
-X0 = np.linspace(-Li,Li,ni)
-Y0 = np.linspace(-Li,Li,ni)
-#Generating meshgrid of points 
-X0,Y0 = np.meshgrid(X0,Y0)
-r0 = np.sqrt( X0**2 + Y0**2 )
-theta = np.zeros((ni,ni))
-epsilon = np.zeros((ni,ni))
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
xc = epsilon*np.cos(theta)
-yc = epsilon*np.sin(theta)
-plt.figure(figsize=(12,6))
-plt.subplot(1,2,1)
-plt.plot(xc,yc,'b.');
-plt.subplot(1,2,2)
-plt.plot(X0,Y0,"b.");
-
- -
-
-
- -
-
- -
- -
-
-

Summary

-
-
-
-
- -
- -
-
-
    -
  • optimize.bisect
  • -
  • optimize.fixed_point
  • -
  • optimize.newton
  • -
- -
-
-
-
- -
- -
-
-

In scipy.optimize the newton method contains both the secant and Newton-Raphson algorithms. The las one is used when the derivative of the function is used explicitly

- -
-
-
-
- -
- -
-
- -
-
-
optimize.newton?
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
import numpy as np
-from scipy import optimize 
-def f(x):
-    return x**2*np.cos(2*x)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
x=np.linspace(-1,1)
-plt.plot( x, f(x), lw=2 )
-plt.grid()
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
def g(x):
-    return x-f(x)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
def fprime(x):
-    "Derivate of f=x**2*np.cos(2x)"
-    return 2*x*np.cos(2*x) - 2*x**2*np.sin(2*x)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
root1=optimize.fixed_point(g,-1.0)
-root2=optimize.fixed_point(g,0.5)
-root3=optimize.fixed_point(g,0.75)
-
-print("las raices son x={} x={} x={}".format(root1,root2,root3))
-
- -
-
-
- -
-
- -
-
- -
-
las raices son x=-0.7853981633974483 x=-4.363697583627993e-09 x=0.7853981633974483
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
f(root1),f(root2),f(root3)
-
- -
-
-
- -
-
- -
-
- - - -
-
(3.777118574576472e-17, 1.9041856601360782e-17, 3.777118574576472e-17)
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#Secant
-root1=optimize.newton(f,-1)
-root2=optimize.newton(f,0.4,tol=1E-16,maxiter=100)
-root3=optimize.newton(f,0.5)
-
-print("las raices son x={} x={} x={}".format(root1,root2,root3))
-
- -
-
-
- -
-
- -
-
- -
-
las raices son x=-0.7853981633974487 x=1.0433087260535526e-16 x=-0.7853981633974482
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
# Newton Raphson
-root1=optimize.newton(f,-1,fprime)
-root2=optimize.newton(f,0.1,fprime,tol=1E-16)
-root3=optimize.newton(f,0.5,fprime)
-
-print("las raices son x={} x={} x={}".format(root1,root2,root3))
-
- -
-
-
- -
-
- -
-
- -
-
las raices son x=-0.7853981633974483 x=8.642260125895126e-17 x=-0.7853981633974484
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
root2=optimize.newton(f,0,fprime)
-root2
-
- -
-
-
- -
-
- -
-
- - - -
-
0.0
-
- -
-
-
-
- -
-
- -
- -
-
-

Brent's method.

Find a root of a function in a bracketing interval using Brent's method.

- -
-
-
-
- -
- -
-
- -
-
-
x=np.linspace(-1,1)
-plt.plot( x, f(x), lw=2 )
-plt.grid()
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
from scipy.optimize import brentq
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
brentq(f,-1,-0.5)
-
- -
-
-
- -
-
- -
-
- - - -
-
-0.7853981633973381
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
brentq(f,-0.5,0.5)
-
- -
-
-
- -
-
- -
-
- -
-
----------------------------------------------------------------------------
-ValueError                                Traceback (most recent call last)
-<ipython-input-62-2741c04b08c2> in <module>
-----> 1 brentq(f,-0.5,0.5)
-
-/usr/local/lib/python3.7/dist-packages/scipy/optimize/zeros.py in brentq(f, a, b, args, xtol, rtol, maxiter, full_output, disp)
-    774     if rtol < _rtol:
-    775         raise ValueError("rtol too small (%g < %g)" % (rtol, _rtol))
---> 776     r = _zeros._brentq(f, a, b, xtol, rtol, maxiter, args, full_output, disp)
-    777     return results_c(full_output, r)
-    778 
-
-ValueError: f(a) and f(b) must have different signs
-
-
-
-
-
- -
-
- - - - -
- \ No newline at end of file diff --git a/_build/features/one-variable-equations.html b/_build/features/one-variable-equations.html deleted file mode 100644 index 5483a90..0000000 --- a/_build/features/one-variable-equations.html +++ /dev/null @@ -1,2532 +0,0 @@ ---- -interact_link: content/features/one-variable-equations.ipynb -kernel_name: python3 -kernel_path: content/features -has_widgets: false -title: |- - One Variable Equations -pagenum: 9 -prev_page: - url: /features/numba.html -next_page: - url: /features/one-variable-equations-fixed-point.html -suffix: .ipynb -search: p b variable ipynb fixed f equations point condition stop example function method steps epsilon x frac colab com convergence e value pi scipy not error root iterations google bisection bm where m github next iteration must right axis n check equation t research svg solution numerical used methods analysis derivation nm using relative very y left sqrt parameters font anomaly src solutions different implicit does index bibliography fp activity br org between interval such within set conditions distance should required precision times implementation help code sin orbital trajectory mean computed semi href restrepo computationalmethods blob master material target parentimg - -comment: "***PROGRAMMATICALLY GENERATED, DO NOT EDIT. SEE ORIGINAL FILES IN /content***" ---- - -
-
One Variable Equations
-
-
- -
-
-

Open In Colab

-

One Variable Equations

Open In Colab

-

Throughout this section and the next ones we shall cover the topic of solutions to one variable equations. Many different problems in physics and astronomy require the use of complex expressions, even with implicit dependence of variables. When it is necessary to solve for one of those variable, an analytical approach is not usually the best solution, because of its complexity or even because it does not exist at all. Different approaches for dealing with this comprehend series expansions and numerical solutions. Among the most widely used numerical approaches are the Bisection or Binary-search method, fixed-point iteration, Newton's methods.

-

For further details see for example Chap. 5 of Ref. (1) or Chap. 4 of Ref. (3)

- -
-
-
-
- - - -
- -
-
- -
-
-
%pylab inline
-rc('animation', html='jshtml')
-
- -
-
-
- -
-
- -
-
- -
-
Populating the interactive namespace from numpy and matplotlib
-
-
-
-
-
-
- -
-
- -
- -
-
-

JSAnimation import available at https://github.com/jakevdp/JSAnimation

- -
-
-
-
- -
- -
-
- -
-
-
#from JSAnimation import IPython_display
-from matplotlib import animation
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
import numpy as np
-from scipy import integrate
-from scipy import optimize
-
- -
-
-
- -
-
- -
- -
-
-

Bisection Method

-
-
-
-
- -
- -
-
-

The Bisection method exploits the intermediate value theorem, where a continuous and differentiable function $f$ must have a zero between an interval $[a,b]$ such that $f(a)f(b)<0$, or equivalently, there must be a value $p\in[a,b]$ such that $f(p)=0$. Below the algorithmm is stated explicitly.

- -
-
-
-
- -
- -
-
-

Steps BM

-
-
-
-
- -
- -
-
-
- -
    -
  1. There must be selected two values $a$ and $b$ such that $f(a)f(b)<0$ and $p\in[a,b]$ where $f(p)=0$. In other words, though we do not know the value of the root, we must know that there is at least one within the selected interval.

    -
  2. -
  3. To begin, it must be set $a_1=a$ and $b_1=b$.

    -
  4. -
  5. Calculate the mid-point $p_1$ as

    -

    $$p_1 = a_1 + \frac{b_1-a_1}{2} = \frac{a_1+b_1}{2}$$

    -
  6. -
  7. Evaluate the function in $p_1$, if the stop condition is true, go to step 6.

    -
  8. -
  9. If the stop condition is not satisfied, then:

    -
      -
    1. If $f(p_1)f(a_1) > 0$, $p\in(p_1,b_1)$. Then set $a_2=p_1$ and $b_2=b_1$

      -
    2. -
    3. If $f(p_1)f(a_1) < 0$, $p\in(a_1,p_1)$. Then set $a_2=a_1$ and $b_2=p_1$

      -
    4. -
    5. Go to step 3 using $p_2$, $a_2$ and $b_2$ instead of $p_1$, $a_1$ and $b_1$. For next iterations the index increases until the stop condition is reached.

      -
    6. -
    -
  10. -
  11. The End!

    -
  12. -
- -
-
-
-
- -
- -
-
-

Stop condition BM

-
-
-
-
- -
- -
-
-

There are several different stop conditions for this algorithm. The most used are stated below:

-
    -
  • A fixed distance between the last two steps (absolute convergence): → xtol

    -

    $$|p_i - p_{i-1}|<\epsilon$$

    -
  • -
  • A fixed relative distance between the last two steps (relative convergence): → rtol

    -

    $$\frac{|p_i - p_{i-1}|}{|p_i|}<\epsilon\ \ \ \ \ p_i \neq 0$$

    -
  • -
  • Function tolerance:

    -

    $$f(p_i)< \epsilon$$

    -
  • -
-

All these conditions should lead to a desired convergence expressed by the $\epsilon$ value. However, the first and the third conditions present some problems when the function has a derivative very large or close to $0$ as evaluated in the root value. When the function is very inclined, the first condition fails as a convergence in the $x$ axis does not guarantee a convergence in the $y$ axis, so the found root $p$ may be far from the real value. When the function is very flat ($dF/dx\rightarrow 0$), the third condition fails due to an analogous reason.

-

A final stop condition which does not have mathematical motivation but a computational one, is a maximum number of allowed iterations. This condition should be used not only for this algorithm but for all iteration-based numerical methods. This condition guarantees a finite computing time and prevents undesired infinite bucles.

-
    -
  • If $N>N_{max}$, stop!
  • -
- -
-
-
-
- -
- -
-
-

Error analysis BM

-
-
-
-
- -
- -
-
-

If we suppose $f\in C[a,b]$ and $f(a)f(b)<0$, the Bisection method generates a sequence of numbers $\left\{p_i\right\}_{i=1}^\infty$ approximating a root $p$ of $f$ as:

-$$|p_i-p|\leq \frac{b-a}{2^n},\ \ \ \ \ i\geq 1$$

From this, we can conclude the convergence rate of the method is

-$$p_i = p + \mathcal{O}\left( \frac{1}{2^i} \right)$$

This expression allows us to estimate the maximum number of required iterations for achieving a desired precision. The next figure sketches the number of iterations required for some precision.

- -
-
-
-
- -
- -
-
- -
-
-
import time
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
i=np.arange( 1, 100)
-i[:3]
-
- -
-
-
- -
-
- -
-
- - - -
-
array([1, 2, 3])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
# plt.plot( x,y  ) # points joined with straight lines 
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
# 1/2**i → exp2(-i)
-plt.plot(i,np.exp2(-i))
-
- -
-
-
- -
-
- -
-
- - - -
-
[<matplotlib.lines.Line2D at 0x7f6a0c45f898>]
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
s=time.time()
-#Array of iterations
-Niter = np.arange( 1, 100 )
-
-plt.figure( figsize=(6,6) )
-#plt.semilogy( Niter, 2.0**-Niter, color="green", lw = 2 )
-plt.semilogy( Niter, np.exp2(-Niter), color="green", lw = 2 )
-plt.grid(True)
-plt.xlabel("Number of Iterations",size=15)
-plt.ylabel("Absolute Error $|p_n-p|$",size=15)
-f=time.time()-s
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Example 1

-
-
-
-
- -
- -
-
-

Find the root of the function $f$

-

$f(x) = x^3 - 2$

-

for $20$ iterations, show the result and the relative error in each iteration.

- -
-
-
-
- -
- -
-
- -
-
-
#Defining Bisection function
-def Bisection( f, a, b, Nmax, printer=False ):
-    """
-    Find the root of function f between a and b
-    
-    f: function
-    a,b: the initial interval
-    Nmax: Nmax de interations
-    printer: bool, to print internal steps
-    """
-    #verifying the STEP1, a and b with different signs
-    import sys
-    if f(a)*f(b)>0:
-        sys.exit("Error, f(a) and f(b) should have opposite signs")
-        return False
-    #Assigning the current extreme values, STEP2
-    ai = a
-    bi = b
-    #Iterations
-    n = 1
-    while n<=Nmax:
-        #Bisection, STEP3
-        pi = (ai+bi)/2.0
-        #Evaluating function in pi, STEP4 and STEP5
-        if printer:
-            print( "Value for {} iterations: {}".format(n,pi) )
-        #Condition A
-        if f(pi)*f(ai)>0:
-            ai = pi
-        #Condition B
-        elif f(pi)*f(ai)<0:
-            bi = pi
-        #Condition C: repeat the cycle
-        n+=1
-    #Final result
-    return pi
-
- -
-
-
- -
-
- -
- -
-
-

Defining function

- -
-
-
-
- -
- -
-
- -
-
-
def function(x):
-    return x**3.0 - 2.0
-
- -
-
-
- -
-
- -
- -
-
-

Finding the root of the function. The real root is $\sqrt[3]{2}$, so a and b should enclose this value

- -
-
-
-
- -
- -
-
- -
-
-
#Defining a and b
-a = 0.0
-b = 2.0
-Nmax = 20
-result = Bisection(function, a, b, Nmax, printer=True)
-print ( "Real value:", 2**(1/3))
-print ( "Absolute error", abs((2**(1/3)-result)) )
-
- -
-
-
- -
-
- -
-
- -
-
Value for 1 iterations: 1.0
-Value for 2 iterations: 1.5
-Value for 3 iterations: 1.25
-Value for 4 iterations: 1.375
-Value for 5 iterations: 1.3125
-Value for 6 iterations: 1.28125
-Value for 7 iterations: 1.265625
-Value for 8 iterations: 1.2578125
-Value for 9 iterations: 1.26171875
-Value for 10 iterations: 1.259765625
-Value for 11 iterations: 1.2607421875
-Value for 12 iterations: 1.26025390625
-Value for 13 iterations: 1.260009765625
-Value for 14 iterations: 1.2598876953125
-Value for 15 iterations: 1.25994873046875
-Value for 16 iterations: 1.259918212890625
-Value for 17 iterations: 1.2599334716796875
-Value for 18 iterations: 1.2599258422851562
-Value for 19 iterations: 1.2599220275878906
-Value for 20 iterations: 1.2599201202392578
-Real value: 1.2599210498948732
-Absolute error 9.296556153781665e-07
-
-
-
-
-
-
- -
-
- -
- -
-
-

Using the error analysis, we can predict the produced error at $20$ iterations by computing:

-$$ \left( \frac{1}{2^{20}}\right) \approx 9.53674316\times 10^{-7} $$

This value is very close to the obtained relative error.

-

If we were interested in a double precision, i.e. $\epsilon \sim 10^{-17}$, the number of required iterations would be:

-$$ 10^{-17} = \left( \frac{1}{2^{N}}\right) \longrightarrow N = \frac{17}{\log_{10}(2)} \approx 56 $$ -
-
-
-
- -
- -
-
-

Now the same but using scipy implementation

- -
-
-
-
- -
- -
-
- -
-
-
from scipy import optimize 
-
- -
-
-
- -
-
- -
- -
-
-

See help with optimize?:

- -
-
-
-
- -
- -
-
- -
-
-
optimize.bisect?
-
- -
-
-
- -
-
- -
- -
-
-

Check the help: See here

- -
-
-
-
- -
- -
-
- -
-
-
def f(x,n,c=2):
-    return x**n-c
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
optimize.bisect(f,0,2,args=(3,)) 
-
- -
-
-
- -
-
- -
-
- - - -
-
1.2599210498938191
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
optimize.bisect(lambda x: f(x,3),0,2)
-
- -
-
-
- -
-
- -
-
- - - -
-
1.2599210498938191
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
help(optimize.bisect)
-
- -
-
-
- -
-
- -
-
- -
-
Help on function bisect in module scipy.optimize.zeros:
-
-bisect(f, a, b, args=(), xtol=2e-12, rtol=8.881784197001252e-16, maxiter=100, full_output=False, disp=True)
-    Find root of a function within an interval using bisection.
-    
-    Basic bisection routine to find a zero of the function `f` between the
-    arguments `a` and `b`. `f(a)` and `f(b)` cannot have the same signs.
-    Slow but sure.
-    
-    Parameters
-    ----------
-    f : function
-        Python function returning a number.  `f` must be continuous, and
-        f(a) and f(b) must have opposite signs.
-    a : scalar
-        One end of the bracketing interval [a,b].
-    b : scalar
-        The other end of the bracketing interval [a,b].
-    xtol : number, optional
-        The computed root ``x0`` will satisfy ``np.allclose(x, x0,
-        atol=xtol, rtol=rtol)``, where ``x`` is the exact root. The
-        parameter must be nonnegative.
-    rtol : number, optional
-        The computed root ``x0`` will satisfy ``np.allclose(x, x0,
-        atol=xtol, rtol=rtol)``, where ``x`` is the exact root. The
-        parameter cannot be smaller than its default value of
-        ``4*np.finfo(float).eps``.
-    maxiter : int, optional
-        If convergence is not achieved in `maxiter` iterations, an error is
-        raised. Must be >= 0.
-    args : tuple, optional
-        Containing extra arguments for the function `f`.
-        `f` is called by ``apply(f, (x)+args)``.
-    full_output : bool, optional
-        If `full_output` is False, the root is returned. If `full_output` is
-        True, the return value is ``(x, r)``, where x is the root, and r is
-        a `RootResults` object.
-    disp : bool, optional
-        If True, raise RuntimeError if the algorithm didn't converge.
-        Otherwise, the convergence status is recorded in a `RootResults`
-        return object.
-    
-    Returns
-    -------
-    x0 : float
-        Zero of `f` between `a` and `b`.
-    r : `RootResults` (present if ``full_output = True``)
-        Object containing information about the convergence. In particular,
-        ``r.converged`` is True if the routine converged.
-    
-    Examples
-    --------
-    
-    >>> def f(x):
-    ...     return (x**2 - 1)
-    
-    >>> from scipy import optimize
-    
-    >>> root = optimize.bisect(f, 0, 2)
-    >>> root
-    1.0
-    
-    >>> root = optimize.bisect(f, -2, 0)
-    >>> root
-    -1.0
-    
-    See Also
-    --------
-    brentq, brenth, bisect, newton
-    fixed_point : scalar fixed-point finder
-    fsolve : n-dimensional root-finding
-
-
-
-
-
-
-
- -
-
- -
- -
-
-

General arguments and options of a SciPy function

-
-
-
-
- -
- -
-
-

Let define a general multiparameter

-
    -
  • f -with a mandatory parameter and two optional parameters, corresponding to a straight line with the slope and the intercept as parameters -$$ -f(x)=mx+b\,, -$$
  • -
- -
-
-
-
- -
- -
-
- -
-
-
def f(x,m=3,b=-2):
-    return m*x+b
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
f(0.66666666666666666,-3,2)
-
- -
-
-
- -
-
- -
-
- - - -
-
0.0
-
- -
-
-
-
- -
-
- -
- -
-
-

We have at least three ways to use a multiparameter function, the first two with the implicit lambda function

- -
-
-
-
- -
- -
-
- -
-
-
optimize.bisect(lambda x: -3*x+2,-10,10)
-
- -
-
-
- -
-
- -
-
- - - -
-
0.6666666666671972
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
optimize.bisect(lambda x: f(x,-3,2),-10,10,)
-
- -
-
-
- -
-
- -
-
- - - -
-
0.6666666666671972
-
- -
-
-
-
- -
-
- -
- -
-
-

and the recommended way to used the designed implementation in Scipy through the args parameter which is common to many methods

- -
-
-
-
- -
- -
-
- -
-
-
optimize.bisect(f,-10,10,args=(-3,2))
-
- -
-
-
- -
-
- -
-
- - - -
-
0.6666666666671972
-
- -
-
-
-
- -
-
- -
- -
-
-
    -
  • xtol
  • -
- -
-
-
-
- -
- -
-
- -
-
-
optimize.bisect(f,-10,10,args=(-3,2),xtol=1E-17)
-
- -
-
-
- -
-
- -
-
- - - -
-
0.6666666666666671
-
- -
-
-
-
- -
-
- -
- -
-
-
    -
  • maxiter
  • -
- -
-
-
-
- -
- -
-
- -
-
-
optimize.bisect(f,-10,10,args=(-3,2),xtol=1E-17,maxiter=10000)
-
- -
-
-
- -
-
- -
-
- - - -
-
0.6666666666666671
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
optimize.bisect(f,-10,10,args=(-3,2),xtol=1E-17,rtol=1E-15,maxiter=10000)
-
- -
-
-
- -
-
- -
-
- - - -
-
0.6666666666666671
-
- -
-
-
-
- -
-
- -
- -
-
-
    -
  • full_output
  • -
- -
-
-
-
- -
- -
-
- -
-
-
x0,r=optimize.bisect(f,-10,10,args=(-3,2),xtol=1E-17,full_output=True)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
x0
-
- -
-
-
- -
-
- -
-
- - - -
-
0.6666666666666671
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
type(r)
-
- -
-
-
- -
-
- -
-
- - - -
-
scipy.optimize.zeros.RootResults
-
- -
-
-
-
- -
-
- -
- -
-
-

Check the code

- -
-
-
-
- -
- -
-
- -
-
-
r.root
-
- -
-
-
- -
-
- -
-
- - - -
-
0.6666666666666671
-
- -
-
-
-
- -
-
- -
- -
-
-

The help of the function is write directly in the code of the Scipy method bisect

- -
-
-
-
- -
- -
-
- -
-
-
optimize.bisect??
-
- -
-
-
- -
-
- -
- -
-
-

Check the internal referenced code

- -
-
-
-
- -
- -
-
- -
-
-
optimize._zeros??
-
- -
-
-
- -
-
- -
-
- - - -
-
Type:        module
-String form: <module 'scipy.optimize._zeros' from '/usr/local/lib/python3.7/dist-packages/scipy/optimize/_zeros.cpython-37m-x86_64-linux-gnu.so'>
-File:        /usr/local/lib/python3.7/dist-packages/scipy/optimize/_zeros.cpython-37m-x86_64-linux-gnu.so
-
-
- -
-
-
-
- -
-
- -
- -
-
-

Example

Find the roots of -$$x^3=2$$

- -
-
-
-
- -
- -
-
- -
-
-
def function(x):
-    return x**3.0 - 2.0
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
todo=optimize.bisect(function,a,b,full_output=True)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
type(todo)
-
- -
-
-
- -
-
- -
-
- - - -
-
tuple
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
len(todo)
-
- -
-
-
- -
-
- -
-
- - - -
-
2
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
result=todo[0]
-result
-
- -
-
-
- -
-
- -
-
- - - -
-
1.2599210498938191
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
r=todo[1]
-r
-
- -
-
-
- -
-
- -
-
- - - -
-
      converged: True
-           flag: 'converged'
- function_calls: 42
-     iterations: 40
-           root: 1.2599210498938191
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
type(r)
-
- -
-
-
- -
-
- -
-
- - - -
-
scipy.optimize.zeros.RootResults
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
r.iterations
-
- -
-
-
- -
-
- -
-
- - - -
-
40
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
todo=optimize.bisect(function,a,b,full_output=False)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
type(todo)
-
- -
-
-
- -
-
- -
-
- - - -
-
float
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
a = 0.0
-b = 2.0
-
-result,r=optimize.bisect(function,a,b,full_output=True)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
result
-
- -
-
-
- -
-
- -
-
- - - -
-
1.2599210498938191
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
2**(1/3.0)
-
- -
-
-
- -
-
- -
-
- - - -
-
1.2599210498948732
-
- -
-
-
-
- -
-
- -
- -
-
-

Check r object by using the <TAB> key next

- -
-
-
-
- -
- -
-
- -
-
-
r.iterations
-
- -
-
-
- -
-
- -
-
- - - -
-
40
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
r.function_calls
-
- -
-
-
- -
-
- -
-
- - - -
-
42
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
2**(-r.iterations)
-
- -
-
-
- -
-
- -
-
- - - -
-
9.094947017729282e-13
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
abs((2**(1/3.0)-result))
-
- -
-
-
- -
-
- -
-
- - - -
-
1.0540457395791236e-12
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
r.converged
-
- -
-
-
- -
-
- -
-
- - - -
-
True
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
result,r=optimize.bisect(function,a,b,xtol=1E-17,full_output=True)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
r.iterations
-
- -
-
-
- -
-
- -
-
- - - -
-
51
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
abs((2**(1/3.0)-result))
-
- -
-
-
- -
-
- -
-
- - - -
-
2.220446049250313e-16
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
2**(-r.iterations)
-
- -
-
-
- -
-
- -
-
- - - -
-
4.440892098500626e-16
-
- -
-
-
-
- -
-
- -
- -
-
-

ACTIVITY

-
-
-
-
- -
- -
-
-

-In an IPython notebook, use the scipy implementation and find the first solution to the equation

-

$ 7 = \sqrt{x^2+1}+e^x\sin x $

-

CLUE: Check graphically (with matplotlib) that the solution is within the interval $[0,2]$. -</font>

- -
-
-
-
- -
- -
-
-

solution

- -
-
-
-
- -
- -
-
- -
-
-
a,b,c=(2,3,4)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
c
-
- -
-
-
- -
-
- -
-
- - - -
-
4
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
import numpy as np
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
# Solo usar para constante
-np.e
-
- -
-
-
- -
-
- -
-
- - - -
-
2.718281828459045
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
np.exp(1)
-
- -
-
-
- -
-
- -
-
- - - -
-
2.718281828459045
-
- -
-
-
-
- -
-
- -
- -
-
-

Example 2

-
-
-
-
- -
- -
-
-

In orbital mechanics, when solving the central-force problem it becomes necessary to solve the Kepler's equation. This is a transcendental equation that relates the orbital parameters of the trajectory.

-

Kepler equation: $M = E - \epsilon \sin E$

-

where $M$ is the mean anomaly, $E$ the eccentric anomaly and $\epsilon$ the eccentricity. The mean anomaly can be computed with the expression

-$$M = n\ t = \sqrt{ \frac{GM}{a^3} } t$$

where $n$ is the mean motion, $G$ the gravitational constant, $M$ the mass of the central body and $a$ the semi-major axis. $t$ is the time where the position in the trajectory will be computed.

-

The coordinates $x$ and $y$ as time functions can be recovered by means of the next expressions

-$$x(t) = a(\cos E - \epsilon)$$$$y(t) = b\sin E$$

where $b = a \sqrt{1-\epsilon^2}$ is the semi-minor axis of the orbit and the implicit time-dependence of the eccentric anomaly $E$ is computed through the Kepler's equation.

- -
-
-
-
- -
- -
-
-

Problem:

-

For a stallite orbiting the earth in a equatorial trajectory with eccentricity $\epsilon = 0.5$ at a geostationary distance for the semi-major axis, tabulate the positions $x$ and $y$ within the orbital plane in intervals of $15$ min during $5$ hours.

-

Parameters:

-
    -
  • $\epsilon = 0.5$

    -
  • -
  • $a = 35900$ km

    -
  • -
  • $G = 6.67384 \times 10^{-11}$ m$^3$ kg$^{-1}$ s$^{-2}$

    -
  • -
  • $M_{\oplus} = 5.972\times 10^{24}$ kg

    -
  • -
- -
-
-
-
- -
- -
-
- -
-
-
#====================================================================
-#Parameters
-#====================================================================
-#Eccentricity
-eps = 0.5
-#Semi-major axis    [m]
-a = 35900e3
-#Gravitational constant    [m3kg-1s-2]
-GC = 6.67384e-11
-#Earth mass    [kg]
-Me = 5.972e24
-
-#Semi-minor axis    [m]
-b = a*(1-eps**2.0)**0.5
-#Mean motion
-n = ( GC*Me/a**3.0 )**0.5
-
-#Hour to Second
-HR2SC = 3600.
-#Initial time    [hr]
-t0 = 0*HR2SC
-#Final time    [hr]
-tf = 5*HR2SC
-#Time step    [hr]
-tstep = 0.25*HR2SC
-#Number of maxim iterations
-Niter = 56
-#Root interval
-a0 = -10
-b0 = 10
-
-#====================================================================
-#Kepler Function
-#====================================================================
-def kepler( E ):
-    func = E - eps*np.sin(E) - n*t
-    return func
-
-#====================================================================
-#Position function
-#====================================================================
-def r(E):
-    x = a*(np.cos(E)-eps)
-    y = b*np.sin(E)
-    return [x/1.e3, y/1.e3]
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
#====================================================================
-#Solving for different times
-#====================================================================
-#Time array
-times = np.arange( t0, tf, tstep )
-
-rpos = []
-for t in times:
-    #Finding the new eccentric anomaly
-    E = optimize.bisect( kepler, a0, b0 )
-    #Computing coordinates at this time
-    ri = r(E)
-    print ("In %f hours, the satellite is located at (%f,%f) km"%(t/HR2SC, ri[0], ri[1]) )
-    rpos.append( ri )
-rpos = np.array(rpos)    
-
-#Plotting
-plt.plot( rpos[:,0], rpos[:,1], "o-", color="red", lw = 2 )
-plt.grid(True)
-plt.xlabel("$x$ coordinate [km]")
-plt.ylabel("$y$ coordinate [km]")
-
- -
-
-
- -
-
- -
-
- -
-
In 0.000000 hours, the satellite is located at (17950.000000,0.000000) km
-In 0.250000 hours, the satellite is located at (17454.741542,5146.426647) km
-In 0.500000 hours, the satellite is located at (16033.097675,10023.437750) km
-In 0.750000 hours, the satellite is located at (13848.847528,14430.262364) km
-In 1.000000 hours, the satellite is located at (11104.379909,18261.701894) km
-In 1.250000 hours, the satellite is located at (7989.437466,21493.410338) km
-In 1.500000 hours, the satellite is located at (4657.168469,24151.489610) km
-In 1.750000 hours, the satellite is located at (1221.066166,26286.121177) km
-In 2.000000 hours, the satellite is located at (-2238.747501,27954.872718) km
-In 2.250000 hours, the satellite is located at (-5667.264143,29214.008624) km
-In 2.500000 hours, the satellite is located at (-9027.373695,30114.739827) km
-In 2.750000 hours, the satellite is located at (-12294.392344,30702.085866) km
-In 3.000000 hours, the satellite is located at (-15452.164136,31014.965936) km
-In 3.250000 hours, the satellite is located at (-18490.361033,31086.789919) km
-In 3.500000 hours, the satellite is located at (-21402.633716,30946.195086) km
-In 3.750000 hours, the satellite is located at (-24185.347784,30617.769816) km
-In 4.000000 hours, the satellite is located at (-26836.717825,30122.702148) km
-In 4.250000 hours, the satellite is located at (-29356.211228,29479.336137) km
-In 4.500000 hours, the satellite is located at (-31744.135350,28703.638662) km
-In 4.750000 hours, the satellite is located at (-34001.350021,27809.586870) km
-
-
-
-
-
-
- - - -
-
Text(0, 0.5, '$y$ coordinate [km]')
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-
- -
-
-
-
- - - - -
- \ No newline at end of file diff --git a/_build/features/overview-python.html b/_build/features/overview-python.html deleted file mode 100644 index 178fa75..0000000 --- a/_build/features/overview-python.html +++ /dev/null @@ -1,5855 +0,0 @@ ---- -interact_link: content/features/overview-python.ipynb -kernel_name: python3 -kernel_path: content/features -has_widgets: true -title: |- - Python overview -pagenum: 1 -prev_page: - url: /index.html -next_page: - url: /features/scientific-libraries.html -suffix: .ipynb -search: python functions list function lists variable example activity org not end colab better hello print x method elements com want methods integer world input check also attributes dictionary google float complex string tuples f html useful dictionaries used format values previous create docs tuple research where implicit its conditionals type called define library sum times extract index element condition keys using master src right www something different program wikipedia en wiki special although should never implementation idea arithmetics bucles types variables standard output must another begin strings code help name here certain data log set l given start comprehensions accessed - -comment: "***PROGRAMMATICALLY GENERATED, DO NOT EDIT. SEE ORIGINAL FILES IN /content***" ---- - -
-
Python overview
-
-
- -
-
-

Open In Colab

- -
-
-
-
- -
- -
-
-
- -

PYTHON

Open In Colab

-

Python is an interpreted programming language oriented to easy-readable coding, unlike compiled languages like C/C++ and Fortran, where the syntax usually does not favor the readability. This feature makes Python very interesting when we want to focus on something different than the program structure itself, e.g. on Computational Methods, thereby allowing to optimize our time, to debug syntax errors easily, etc.

-

Official page

-

Wikipedia

-

Python Philosophy

    -
  1. Beautiful is better than ugly.
  2. -
  3. Explicit is better than implicit.
  4. -
  5. Simple is better than complex.
  6. -
  7. Complex is better than complicated.
  8. -
  9. Flat is better than nested.
  10. -
  11. Sparse is better than dense.
  12. -
  13. Readability counts.
  14. -
  15. Special cases aren't special enough to break the rules. (Although practicality beats purity)
  16. -
  17. Errors should never pass silently. (Unless explicitly silenced)
  18. -
  19. In the face of ambiguity, refuse the temptation to guess.
  20. -
  21. There should be one-- and preferably only one --obvious way to do it. (Although that way may not be obvious at first unless you're Dutch)
  22. -
  23. Now is better than never. (Although never is often better than right now)
  24. -
  25. If the implementation is hard to explain, it's a bad idea.
  26. -
  27. If the implementation is easy to explain, it may be a good idea.
  28. -
  29. NameSpaces are one honking great idea -- let's do more of those!
  30. -
- -
-
-
-
- -
- -
-
-
- -
-
-
-
- - - -
- -
-
-
- -
-
-
-
- -
- -
-
-

String, Integer, Float

The basic types of variables in Python are:

- -
-
-
-
- -
- -
-
-

str:

- -
-
-
-
- -
- -
-
-

Illustrated with the hello world standard

- -
-
-
-
- -
- -
-
- -
-
-
#Strings
-hello='hola'
-
- -
-
-
- -
-
- -
- -
-
-

int

- -
-
-
-
- -
- -
-
- -
-
-
#Integer
-n=3
-
- -
-
-
- -
-
- -
- -
-
-

float

- -
-
-
-
- -
- -
-
- -
-
-
x=3.5
-
- -
-
-
- -
-
- -
- -
-
-

Functions I

Python includes a battery of predefined functions which takes an input and generates an output. For example, to check the type of variable we can used the -predefined function

-

isinistance:

-
-
-
-
- -
- -
-
- -
-
-
isinstance(hello,str)
-
- -
-
-
- -
-
- -
-
- - - -
-
True
-
- -
-
-
-
- -
-
- -
- -
-
-

Activity: In the next cell check if n is a float type of variable

- -
-
-
-
- -
- -
-
-

print

-
-
-
-
- -
- -
-
-

See: https://pyformat.info/

-

To write the Hello world program in python we must first introduce the concept of function. It is the same in mathematics, were something called function receives a number and return back another number. For example, the function to square a number is -\begin{equation} -f(x)=x^2\,, -\end{equation} -$x$ is called the argument of the function $f$, and the returned value is the evaluation of $f(x)$.

-

In Python there are a lot of such a functions. -In particular there is a function called print which takes strings (see below) as input and return the same string as output. In this way, the hello world program in Python is one of the most simple between all the programming languages:

- -
-
-
-
- -
- -
-
-

Hello World!

-
-
-
-
- -
- -
-
- -
-
-
print('Hello World!')
-
- -
-
-
- -
-
- -
-
- -
-
Hello World!
-
-
-
-
-
-
- -
-
- -
- -
-
-

And also allows scripting: (This code should be copied on a file 'hello.py')

- -
-
-
-
- -
- -
-
- -
-
-
#! /usr/bin/python
-
-#This is a comment
-print('Hello World!')
-
- -
-
-
- -
-
- -
-
- -
-
Hello World!
-
-
-
-
-
-
- -
-
- -
- -
-
-

The recommended way to print a variable in Python is to use the .format method of the function print:

- -
-
-
-
- -
- -
-
- -
-
-
hello='Hello World!'
-print('{}'.format(hello))
-
- -
-
-
- -
-
- -
-
- -
-
Hello World!
-
-
-
-
-
-
- -
-
- -
- -
-
-

Activity: Change the values of the previous string variables to print Hello World! in Spanish

- -
-
-
-
- -
- -
-
-

Functions

-
-
-
-
- -
- -
-
-

In Python it is possible also to create new functions. We illustrate the format to define a function in Python with the implementation of the function $f(x)=x^2$, where to write an exponent: ${}^2$, in Python we must use the format: **2.

- -
-
-
-
- -
- -
-
-

Implicit functions

-
-
-
-
- -
- -
-
- -
-
-
f=lambda x:x**2
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
isinstance(f,str)
-
- -
-
-
- -
-
- -
-
- - - -
-
False
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
type(f)
-
- -
-
-
- -
-
- -
-
- - - -
-
function
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
f(3)
-
- -
-
-
- -
-
- -
-
- - - -
-
9
-
- -
-
-
-
- -
-
- -
- -
-
-

Explicit functions

-
-
-
-
- -
- -
-
-

The standard function build may include the help for the function

- -
-
-
-
- -
- -
-
- -
-
-
def f(x):
-    '''
-    Calculates the square of `x`
-    '''
-    return x**2
-
- -
-
-
- -
-
- -
- -
-
-

f(5)

- -
-
-
-
- -
- -
-
- -
-
-
help(f)
-
- -
-
-
- -
-
- -
-
- -
-
Help on function f in module __main__:
-
-f(x)
-    Calculates the square of `x`
-
-
-
-
-
-
-
- -
-
- -
- -
-
-

The full list of built-in functions is in https://docs.python.org/3/library/functions.html and the specific help for a function, for example print can be checked with https://docs.python.org/3/library/functions.html#print

- -
-
-
-
- -
- -
-
- -
-
-
def f(x,y):
-    '''
-    Multiply two numbers
-    '''
-    return x*y
-f(3,2)
-
- -
-
-
- -
-
- -
-
- - - -
-
6
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#It is possible to assign default arguments
-def f(x,y=2):
-    '''
-    Multiply two numbers. By default the second is 2
-    '''    
-    return x*y
-#When evaluating, we can omit the default argument
-f(3)
-
- -
-
-
- -
-
- -
-
- - - -
-
6
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
f(2,3)
-
- -
-
-
- -
-
- -
-
- - - -
-
6
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
f(2,y=5)
-
- -
-
-
- -
-
- -
-
- - - -
-
10
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#It is possible to specify explicitly the order of the arguments
-def f(x,y):
-    '''
-    evaluates x to the power y
-    '''    
-    return x**y
-print( 'f(1,2)=',f(1,2) )
-print( 'f(2,1)=',f(y=1,x=2) )
-
- -
-
-
- -
-
- -
-
- -
-
f(1,2)= 1
-f(2,1)= 2
-
-
-
-
-
-
- -
-
- -
- -
-
-

Implicit functions of several arguments

-
-
-
-
- -
- -
-
-

Implicit functions are usdeful when we want to use a function once.

- -
-
-
-
- -
- -
-
- -
-
-
f = lambda x,y: x**y
-f(3,2)
-
- -
-
-
- -
-
- -
-
- - - -
-
9
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#It is possible to pass functions as arguments of other function
-def f2( f, x ):
-    return f(x)**2
-
-#We can define a new function explicitly
-def f(x):
-    return x+2
-
-print(f(2))
-print(f2(f,2))
-
-
-#Or define the function implicitly
-print ("Implicit: f(2)^2 =", f2(lambda x:x+2,2) )
-
- -
-
-
- -
-
- -
-
- -
-
4
-16
-Implicit: f(2)^2 = 16
-
-
-
-
-
-
- -
-
- -
- -
-
-

Arithmetics

-
-
-
-
- -
- -
-
-

Sum

-
-
-
-
- -
- -
-
- -
-
-
5.89+4.89
-
- -
-
-
- -
-
- -
-
- - - -
-
10.78
-
- -
-
-
-
- -
-
- -
- -
-
-

Activity: Sum strings: -Hint: use +' '+

- -
-
-
-
- -
- -
-
-

Activity: Sum integers

- -
-
-
-
- -
- -
-
- -
-
-
2+3
-
- -
-
-
- -
-
- -
-
- - - -
-
5
-
- -
-
-
-
- -
-
- -
- -
-
-

Example

- -
-
-
-
- -
- -
-
- -
-
-
print(hello+' '+world+'!')
-
- -
-
-
- -
-
- -
-
- -
-
Hola Mundo!
-
-
-
-
-
-
- -
-
- -
- -
-
-

Multiplication

-
-
-
-
- -
- -
-
- -
-
-
120*4.5
-
- -
-
-
- -
-
- -
-
- - - -
-
540.0
-
- -
-
-
-
- -
-
- -
- -
-
-

Example String multiplied by integer:

- -
-
-
-
- -
- -
-
- -
-
-
print('='*80)
-
- -
-
-
- -
-
- -
-
- -
-
================================================================================
-
-
-
-
-
-
- -
-
- -
- -
-
-

Division

-
-
-
-
- -
- -
-
- -
-
-
#Python 3 does support complete division
-100/3
-
- -
-
-
- -
-
- -
-
- - - -
-
33.333333333333336
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
100/3.
-
- -
-
-
- -
-
- -
-
- - - -
-
33.333333333333336
-
- -
-
-
-
- -
-
- -
- -
-
-

Force integer division

- -
-
-
-
- -
- -
-
- -
-
-
100//3
-
- -
-
-
- -
-
- -
-
- - - -
-
33
-
- -
-
-
-
- -
-
- -
- -
-
-

Module

-
-
-
-
- -
- -
-
- -
-
-
10%2
-
- -
-
-
- -
-
- -
-
- - - -
-
0
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
20%3
-
- -
-
-
- -
-
- -
-
- - - -
-
2
-
- -
-
-
-
- -
-
- -
- -
-
-

Power

-
-
-
-
- -
- -
-
- -
-
-
2**6
-
- -
-
-
- -
-
- -
-
- - - -
-
64
-
- -
-
-
-
- -
-
- -
- -
-
-

Scientific notation

-
-
-
-
- -
- -
-
-

$1\times 10^3=10^3=1000$

- -
-
-
-
- -
- -
-
- -
-
-
1E3
-
- -
-
-
- -
-
- -
-
- - - -
-
1000.0
-
- -
-
-
-
- -
-
- -
- -
-
-

$2\times 10^3=2000$

- -
-
-
-
- -
- -
-
- -
-
-
2E3
-
- -
-
-
- -
-
- -
-
- - - -
-
2000.0
-
- -
-
-
-
- -
-
- -
- -
-
-$$\frac{ \dfrac{10^{24}}{3}+2.9\times 10^{23}}{10^2}$$ -
-
-
-
- -
- -
-
- -
-
-
(1.0e24/3. + 2.9e23)/1e-2
-
- -
-
-
- -
-
- -
-
- - - -
-
6.233333333333333e+25
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
sin=0.3
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
from math import *
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
isinstance(sin,float)
-
- -
-
-
- -
-
- -
-
- - - -
-
False
-
- -
-
-
-
- -
-
- -
- -
-
-

Keep the name space

- -
-
-
-
- -
- -
-
-

Use name.last_name

- -
-
-
-
- -
- -
-
- -
-
-
sin=0.3
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
import math as m
-import cmath as cm
-import numpy as np
-import scipy as sp
-#Recommended option:
-import numpy.lib.scimath as sc
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
isinstance(sin,float)
-
- -
-
-
- -
-
- -
-
- - - -
-
True
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
m.sin(0.5)
-
- -
-
-
- -
-
- -
-
- - - -
-
0.479425538604203
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
cm.sin(0.5)
-
- -
-
-
- -
-
- -
-
- - - -
-
(0.479425538604203+0j)
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
np.sin(0.5)
-
- -
-
-
- -
-
- -
-
- - - -
-
0.479425538604203
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
sp.sin(0.5)
-
- -
-
-
- -
-
- -
-
- -
-
/home/restrepo/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:1: DeprecationWarning: scipy.sin is deprecated and will be removed in SciPy 2.0.0, use numpy.sin instead
-  """Entry point for launching an IPython kernel.
-
-
-
-
-
-
- - - -
-
0.479425538604203
-
- -
-
-
-
- -
-
- -
- -
-
-

Complex numbers

-
-
-
-
- -
- -
-
- -
-
-
1j**2
-
- -
-
-
- -
-
- -
-
- - - -
-
(-1+0j)
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
z=2+3.2j
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
isinstance(z,complex)
-
- -
-
-
- -
-
- -
-
- - - -
-
True
-
- -
-
-
-
- -
-
- -
- -
-
-

Attributes and methods:

- -
-
-
-
- -
- -
-
- -
-
-
z.real,z.imag,z.conjugate()
-
- -
-
-
- -
-
- -
-
- - - -
-
(2.0, 3.2, (2-3.2j))
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
z+3*z
-
- -
-
-
- -
-
- -
-
- - - -
-
(8+12.8j)
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
z*z
-
- -
-
-
- -
-
- -
-
- - - -
-
(-6.240000000000002+12.8j)
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
z*z.conjugate()
-
- -
-
-
- -
-
- -
-
- - - -
-
(14.240000000000002+0j)
-
- -
-
-
-
- -
-
- -
- -
-
-

math does not work with complex numbers

- -
-
-
-
- -
- -
-
- -
-
-
m.asin(2+0j)
-
- -
-
-
- -
-
- -
-
- -
-
----------------------------------------------------------------------------
-TypeError                                 Traceback (most recent call last)
-<ipython-input-162-1385535d58fd> in <module>
-----> 1 m.asin(2+0j)
-
-TypeError: can't convert complex to float
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
cm.asin(2)
-
- -
-
-
- -
-
- -
-
- - - -
-
(1.5707963267948966+1.3169578969248166j)
-
- -
-
-
-
- -
-
- -
- -
-
-

numpy requires proper input

- -
-
-
-
- -
- -
-
- -
-
-
np.arcsin(2)
-
- -
-
-
- -
-
- -
-
- -
-
/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:1: RuntimeWarning: invalid value encountered in arcsin
-  """Entry point for launching an IPython kernel.
-
-
-
-
-
-
- - - -
-
nan
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
np.arcsin(2+0j)
-
- -
-
-
- -
-
- -
-
- - - -
-
(1.5707963267948966+1.3169578969248166j)
-
- -
-
-
-
- -
-
- -
- -
-
-

numpy.lib.scimath imported as sc here, is from sc?:

-

Wrapper functions to more user-friendly calling of certain math functions -whose output data-type is different than the input data-type in certain -domains of the input. -Function with some parts of its domain in the complex plane like, sqrt, log, log2, logn, log10, power, arccos, arcsin, and arctanh.

-
- -
-
-
-
- -
- -
-
- -
-
-
np.lib.scimath.arcsin(2)
-
- -
-
-
- -
-
- -
-
- - - -
-
(1.5707963267948966+1.3169578969248166j)
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
sc.arcsin(2)
-
- -
-
-
- -
-
- -
-
- - - -
-
(1.5707963267948966+1.3169578969248166j)
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
import ipywidgets as widgets
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
@widgets.interact
-def f(x=(0,2)):
-    print(np.abs(sc.arcsin(x)))
-
- -
-
-
- -
-
- -
-
- - - - - - -
-
- - -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
sc.arcsin([2,3])
-
- -
-
-
- -
-
- -
-
- - - -
-
array([1.57079633+1.3169579j , 1.57079633+1.76274717j])
-
- -
-
-
-
- -
-
- -
- -
-
-

Lists, Tuples and Dictionaries

-
-
-
-
- -
- -
-
-

Lists

-
-
-
-
- -
- -
-
-

Lists are useful when you want to store and manipulate a set of elements (even of different types).

- -
-
-
-
- -
- -
-
- -
-
-
#A list is declared using [] and may content different type of objects
-lista = ["abc", 42, 3.1415]
-lista
-
- -
-
-
- -
-
- -
-
- - - -
-
['abc', 42, 3.1415]
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#First element of the list
-lista[0]
-
- -
-
-
- -
-
- -
-
- - - -
-
'abc'
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#Last element of the list
-lista[-1]
-
- -
-
-
- -
-
- -
-
- - - -
-
3.1415
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
isinstance(True,bool)
-
- -
-
-
- -
-
- -
-
- - - -
-
True
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#Adding a new element (boolean element)
-lista.append(True)
-lista
-
- -
-
-
- -
-
- -
-
- - - -
-
['abc', 42, 3.1415, True]
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#Inserting a new second element 
-lista.insert(1, "I am second")
-lista
-
- -
-
-
- -
-
- -
-
- - - -
-
['abc', 'I am second', 42, 3.1415, True]
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#Deleting the third element of the list
-del lista[3]
-lista
-
- -
-
-
- -
-
- -
-
- - - -
-
['abc', 'I am second', 42, True]
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#Reassign the first element of the list
-lista[0] = "xyz"
-lista
-
- -
-
-
- -
-
- -
-
- - - -
-
['xyz', 'I am second', 42, True]
-
- -
-
-
-
- -
-
- -
- -
-
-

Slicing:

Extract elements from a list, l from one given index to another given index. We pass slice instead of index like this:

-
l[start:end]
-
-

We can also define the step, like this:

-
l[start:end:step]
-
-

If start is not passed it is considered 0. If end is not passed it is considered length of array in that dimension. The end can given in reverse order by assigning a minus signus to the index. For example -1 means the last element, whicle -2 means the penultimate, and so on and so forth.

- -
-
-
-
- -
- -
-
- -
-
-
#Showing the elements from 0 to 2
-lista[0:3]
-
- -
-
-
- -
-
- -
-
- - - -
-
['xyz', 'I am second', 42]
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#Showing the last two elements
-lista[-2:]
-
- -
-
-
- -
-
- -
-
- - - -
-
[42, True]
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#Showing elements two by two
-lista[::2]
-
- -
-
-
- -
-
- -
-
- - - -
-
['xyz', 42]
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#Reverse order
-lista[::-1]
-
- -
-
-
- -
-
- -
-
- - - -
-
[True, 42, 'I am second', 'xyz']
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
lista
-
- -
-
-
- -
-
- -
-
- - - -
-
['xyz', 'I am second', 42, True]
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#also as
-lista.reverse()
-lista
-
- -
-
-
- -
-
- -
-
- - - -
-
[True, 42, 'I am second', 'xyz']
-
- -
-
-
-
- -
-
- -
- -
-
-

Embedded lists

-
-
-
-
- -
- -
-
- -
-
-
#It is possible to embed a list
-embedded_list = [lista, [True, 42]]
-embedded_list
-
- -
-
-
- -
-
- -
-
- - - -
-
[[True, 42, 'I am second', 'xyz'], [True, 42]]
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#Second element of the first list
-embedded_list[0][1]
-
- -
-
-
- -
-
- -
-
- - - -
-
42
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#A matrix as a list of embedded lists
-A = [ [1,2], [3,4] ]
-A
-
- -
-
-
- -
-
- -
-
- - - -
-
[[1, 2], [3, 4]]
-
- -
-
-
-
- -
-
- -
- -
-
-

Activity: Obtain entry $A_{01}$ of the previous matrix, where -\begin{align} -A=\begin{pmatrix} -A_{00} & A_{01}\\ -A_{10} & A_{11}\\ -\end{pmatrix} -\end{align}

- -
-
-
-
- -
- -
-
-

Sum of lists

-
-
-
-
- -
- -
-
- -
-
-
#When two list are added, the result is a new concatenated list
-[1,2,"ab",True,[1,2]] + [3.1415,"Pi","circle"]
-
- -
-
-
- -
-
- -
-
- - - -
-
[1, 2, 'ab', True, [1, 2], 3.1415, 'Pi', 'circle']
-
- -
-
-
-
- -
-
- -
- -
-
-

Activity Add a third row with integer values to the previous $A$ matrix -

- -
-
-
-
- -
- -
-
-

An additional ingredient is the append method of a Python list. It update the elements of the list without update explicitly the variable with some equal reasignment.

- -
-
-
-
- -
- -
-
- -
-
-
y=[]
-y.append(2)
-print('after append 2 to [] : {}'.format(y))
-y.append(5)
-print('after append 5 to [2]: {}'.format(y))
-
- -
-
-
- -
-
- -
-
- -
-
after append 2 to [] : [2]
-after append 5 to [2]: [2, 5]
-
-
-
-
-
-
- -
-
- -
- -
-
-

List Comprehensions

-
-
-
-
- -
- -
-
-

Taken from here: List comprehensions provide a concise way to create lists. Common applications are to make new lists where each element is the result of some operations applied to each member of another sequence or iterable, or to create a subsequence of those elements that satisfy a certain condition.

- -
-
-
-
- -
- -
-
- -
-
-
[x**2 for x in range(10)]
-
- -
-
-
- -
-
- -
-
- - - -
-
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
[(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
-
- -
-
-
- -
-
- -
-
- - - -
-
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
l=[ ['A','B','C'],['D','E','F'],['G','H','I']  ]
-
- -
-
-
- -
-
- -
- -
-
-

we can extract the list that contains 'H'

- -
-
-
-
- -
- -
-
- -
-
-
[  [s for s in ll if 'H' in ll ] for ll in l if len( [s for s in ll if 'H' in ll ]) >0]
-
- -
-
-
- -
-
- -
-
- - - -
-
[['G', 'H', 'I']]
-
- -
-
-
-
- -
-
- -
- -
-
-

Reversed comprehension

We can use the method reversed(...) to generate an iterator with the revesersed list so that the original list is kept.

- -
-
-
-
- -
- -
-
- -
-
-
lista
-
- -
-
-
- -
-
- -
-
- - - -
-
[True, 42, 'I am second', 'xyz']
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
print('reversed: {}'.format( list(reversed(lista)) ))
-print('original: {}'.format(lista))
-
- -
-
-
- -
-
- -
-
- -
-
reversed: ['xyz', 'I am second', 42, True]
-original: [True, 42, 'I am second', 'xyz']
-
-
-
-
-
-
- -
-
- -
- -
-
-

Tuples

-
-
-
-
- -
- -
-
-

A tuple is almost equal to a list, except that once declared its elements, it is not possible to modify them. Therefore, tuples are useful only when you want to store some elements but not modify them.

- -
-
-
-
- -
- -
-
- -
-
-
#A tuple is declared using ()
-tupla = ("abc", 42, 3.1415)
-tupla
-
- -
-
-
- -
-
- -
-
- - - -
-
('abc', 42, 3.1415)
-
- -
-
-
-
- -
-
- -
- -
-
-

Note: single element tuple

- -
-
-
-
- -
- -
-
- -
-
-
(2) #equivalent to 2
-
- -
-
-
- -
-
- -
-
- - - -
-
2
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
t=(2,)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
len(t)
-
- -
-
-
- -
-
- -
-
- - - -
-
1
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
t[0]
-
- -
-
-
- -
-
- -
-
- - - -
-
2
-
- -
-
-
-
- -
-
- -
- -
-
-

The comprenhension tuple also works

- -
-
-
-
- -
- -
-
- -
-
-
tuple( (t for t in tupla)  )
-
- -
-
-
- -
-
- -
-
- - - -
-
('abc', 42, 3.1415)
-
- -
-
-
-
- -
-
- -
- -
-
-

any can extract a true value from a comprension tuple (see also all: https://docs.python.org/3/library/functions.html#all). -In fact, for the following nested list:

- -
-
-
-
- -
- -
-
- -
-
-
l=[ ['A','B','C'],['D','E','F'],['G','H','I']   ]
-
- -
-
-
- -
-
- -
- -
-
-

we can extract the list that contains 'H' more easily

- -
-
-
-
- -
- -
-
- -
-
-
[ll for ll in l]
-
- -
-
-
- -
-
- -
-
- - - -
-
[['A', 'B', 'C'], ['D', 'E', 'F'], ['G', 'H', 'I']]
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
any((s=='L' for s in ['G', 'H', 'I']))
-
- -
-
-
- -
-
- -
-
- - - -
-
False
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
[ll for ll in l if any( s=='H' for s in ll  ) ]
-
- -
-
-
- -
-
- -
-
- - - -
-
[['G', 'H', 'I']]
-
- -
-
-
-
- -
-
- -
- -
-
-

With the function zip we can generate dictionary-like tuple from two lists:

- -
-
-
-
- -
- -
-
- -
-
-
list(zip( ['A','B','C'],[1,2,3]  ))
-
- -
-
-
- -
-
- -
-
- - - -
-
[('A', 1), ('B', 2), ('C', 3)]
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
list(zip( ['A','B','C'],[1,2,3]  ))
-
- -
-
-
- -
-
- -
-
- - - -
-
[('A', 1), ('B', 2), ('C', 3)]
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#It is not possible to add more elements
-tupla.append("xy")
-
- -
-
-
- -
-
- -
-
- -
-
----------------------------------------------------------------------------
-AttributeError                            Traceback (most recent call last)
-<ipython-input-87-4cc56b436273> in <module>
-      1 #It is not possible to add more elements
-----> 2 tupla.append("xy")
-
-AttributeError: 'tuple' object has no attribute 'append'
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
#It is not possible to delete an element
-del tupla[0]
-
- -
-
-
- -
-
- -
-
- -
-
----------------------------------------------------------------------------
-TypeError                                 Traceback (most recent call last)
-<ipython-input-88-c05ec550c1d0> in <module>
-      1 #It is not possible to delete an element
-----> 2 del tupla[0]
-
-TypeError: 'tuple' object doesn't support item deletion
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
#It is not possible to modify an existing element
-tupla[0] = "xy"
-
- -
-
-
- -
-
- -
-
- -
-
----------------------------------------------------------------------------
-TypeError                                 Traceback (most recent call last)
-<ipython-input-89-4e97d1641827> in <module>
-      1 #It is not possible to modify an existing element
-----> 2 tupla[0] = "xy"
-
-TypeError: 'tuple' object does not support item assignment
-
-
-
-
-
- -
-
- -
- -
-
-

Dictionaries

-
-
-
-
- -
- -
-
-

Dictionaries are labeled lists: with keys and values. They are extremely useful when manipulating complex data.

- -
-
-
-
- -
- -
-
- -
-
-
#A dictionary is declared using {}, and specifying the name of the component, then the character : followed by the element to store.
-dictionary={ 'Kenia'         :'Nairobi',
-             'Noruega'       :'Oslo',
-             'Finlandia'     :'Helsinski',
-             'Rusia'         :'Moscú',
-             'Rio de Janeiro':'Rio',
-             'Japón'         :'Tokio',
-             'Colorado'      :'Denver',
-             'Alemania'      :'Berlin',
-             'Colombia'      :'Bogotá'}
-print(dictionary)
-#Note the order in a dictionary does not matter as one identifies a single element through a string, not a number
-
- -
-
-
- -
-
- -
-
- -
-
{'Kenia': 'Nairobi', 'Noruega': 'Oslo', 'Finlandia': 'Helsinski', 'Rusia': 'Moscú', 'Rio de Janeiro': 'Rio', 'Japón': 'Tokio', 'Colorado': 'Denver', 'Alemania': 'Berlin', 'Colombia': 'Bogotá'}
-
-
-
-
-
-
- -
-
- -
- -
-
-

Instead of a number, an element of a dictionary is accessed with the key of the component

- -
-
-
-
- -
- -
-
- -
-
-
dictionary
-
- -
-
-
- -
-
- -
-
- - - -
-
{'Kenia': 'Nairobi',
- 'Noruega': 'Oslo',
- 'Finlandia': 'Helsinski',
- 'Rusia': 'Moscú',
- 'Rio de Janeiro': 'Rio',
- 'Japón': 'Tokio',
- 'Colorado': 'Denver',
- 'Alemania': 'Berlin',
- 'Colombia': 'Bogotá'}
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
print('{}{}'.format( dictionary['Japón'], dictionary['Rio de Janeiro']) )
-
- -
-
-
- -
-
- -
-
- -
-
Tokio ♥ Rio
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
#The elements of the dictionary may be of any type
-dictionary2 = { "Enteros":[1,2,3,4,5], 
-                "Ciudad" :"Medellin", 
-                "Cédula" :1128400433, 
-                "Colores":["Amarillo", "Azul", "Rojo"] }
-print(dictionary2["Colores"][1])
-
- -
-
-
- -
-
- -
-
- -
-
Azul
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
#The elements of the dictionary can be modified only by changing directly such an element
-dictionary2["Ciudad"] = "Bogota"
-print(dictionary2)
-
- -
-
-
- -
-
- -
-
- -
-
{'Enteros': [1, 2, 3, 4, 5], 'Ciudad': 'Bogota', 'Cédula': 1128400433, 'Colores': ['Amarillo', 'Azul', 'Rojo']}
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
#Adding a new element is possible by only defining the new component
-dictionary2["Pais"] = "Colombia"
-dictionary2["País"] = "Colombia"
-print( dictionary2 )
-
- -
-
-
- -
-
- -
-
- -
-
{'Enteros': [1, 2, 3, 4, 5], 'Ciudad': 'Bogota', 'Cédula': 1128400433, 'Colores': ['Amarillo', 'Azul', 'Rojo'], 'Pais': 'Colombia', 'País': 'Colombia'}
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
#dictionary2.update({'Pais':'Colombia'})
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
#The command del can be also used for deleting an element, as a list
-del dictionary2["Pais"]
-print(dictionary2)
-
- -
-
-
- -
-
- -
-
- -
-
{'Enteros': [1, 2, 3, 4, 5], 'Ciudad': 'Bogota', 'Cédula': 1128400433, 'Colores': ['Amarillo', 'Azul', 'Rojo'], 'País': 'Colombia'}
-
-
-
-
-
-
- -
-
- -
- -
-
-

With the previous zip function to create tuples from lists, we can create a dictionary from the two lists:

- -
-
-
-
- -
- -
-
- -
-
-
dict(zip( ['A','B','C'],[1,2,3]  ))
-
- -
-
-
- -
-
- -
-
- - - -
-
{'A': 1, 'B': 2, 'C': 3}
-
- -
-
-
-
- -
-
- -
- -
-
-

Activity: Creates a diccionary for the values: ['xyz',3,4.5] with integer keys starting with zero. In this way, the dictionary could behave as list

- -
-
-
-
- -
- -
-
- -
-
-
l={}
-l[0]='xyz'
-l[1]=3
-l[2]=4.5
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
l
-
- -
-
-
- -
-
- -
-
- - - -
-
{0: 'xyz', 1: 3, 2: 4.5}
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
l[0]
-
- -
-
-
- -
-
- -
-
- - - -
-
'xyz'
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
d[3]=5.5
-
- -
-
-
- -
-
- -
- -
-
-

Bucles and Conditionals

-
-
-
-
- -
- -
-
-

if

-
-
-
-
- -
- -
-
-

Conditionals are useful when we want to check some condition. -The statements elif and else can be used when more than one condition need to be used, or when there is something to do when some condition is not fulfilled.

- -
-
-
-
- -
- -
-
- -
-
-
x = 10
-y = 2
-if x > 5 and y==2:
-    print( "True" )
-
- -
-
-
- -
-
- -
-
- -
-
True
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
x = 4
-y = 3
-if x>5 or y<2:
-    print( "True 1" )
-elif x==4:
-    print( "True 2" )
-else:
-    print( "False" )
-
- -
-
-
- -
-
- -
-
- -
-
True 2
-
-
-
-
-
-
- -
-
- -
- -
-
-

for

-
-
-
-
- -
- -
-
-

For cycles are specially useful when we want to sweep a set of elements with a known size.

- -
-
-
-
- -
- -
-
- -
-
-
for i in range(0,5,1):
-    print( i, i**2)
-
- -
-
-
- -
-
- -
-
- -
-
0 0
-1 1
-2 4
-3 9
-4 16
-
-
-
-
-
-
- -
-
- -
- -
-
-

Activity: change print with format

- -
-
-
-
- -
- -
-
- -
-
-
suma = 0
-for i in range(0,10,1):
-    suma += i**2 # suma = suma + i**2
-print ( "The result is %d"%(suma) )
-
- -
-
-
- -
-
- -
-
- -
-
The result is 285
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
for language in ['Python', 'C', 'C++', 'Ruby', 'Java']:
-    print ( language )
-
- -
-
-
- -
-
- -
-
- -
-
Python
-C
-C++
-Ruby
-Java
-
-
-
-
-
-
- -
-
- -
- -
-
-

As we see before, for can be used to build comprenhension lists

- -
-
-
-
- -
- -
-
- -
-
-
serie = [ i**2 for i in range(1,10) ]
-print( serie )
-
- -
-
-
- -
-
- -
-
- -
-
[1, 4, 9, 16, 25, 36, 49, 64, 81]
-
-
-
-
-
-
- -
-
- -
- -
-
-

while

-
-
-
-
- -
- -
-
-

While cycles are specially useful when we want to sweep a set of elements with an unknown size.

- -
-
-
-
- -
- -
-
-

Before we check the functions input and int of Python

- -
-
-
-
- -
- -
-
- -
-
-
edad=input('¿What is your age, Jesus?:\n')
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
int(edad)
-
- -
-
-
- -
-
- -
-
- - - -
-
33
-
- -
-
-
-
- -
-
- -
- -
-
-

Bonus: some time the input must be hidden

- -
-
-
-
- -
- -
-
- -
-
-
import getpass
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
c=getpass.getpass('Contraseña')
-
- -
-
-
- -
-
- -
-
- - -
-
-
-
- -
-
- -
- -
-
- -
-
-
c
-
- -
-
-
- -
-
- -
-
- - - -
-
'1234'
-
- -
-
-
-
- -
-
- -
- -
-
-

Now the while examples

- -
-
-
-
- -
- -
-
- -
-
-
#! /usr/bin/python
-number = int(input("Write a negative number: "))
-while number > 0:
-    print("You wrote a positive number. Do it again")
-    number = int(input("Write a negative number: "))
-print("Thank you!")
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
import random
-x = 0
-while x<0.9:
-    x = random.random()
-    print( x )
-print ("The selected number was", x )
-
- -
-
-
- -
-
- -
-
- -
-
0.8014478544604644
-0.16730340110095598
-0.22609305175080763
-0.3910061658713566
-0.16471583849093963
-0.03893794385343341
-0.9631958511875766
-The selected number was 0.9631958511875766
-
-
-
-
-
-
- -
-
- -
- -
-
-

Methods and attributes of objects in Python

All the objects in Python, including the function and variable types discussed here, are enhanced with special functions called methods, which are implemented after a point of the name of the variable, in the format:

-
variable.method()
-
-

Some times, the method can even accept some arguments.

-

The objects have also attributes which describe some property of the object. They do not end up with parenthesis:

-
variable.attribute
-
- -
-
-
-
- -
- -
-
-

Methods

For example. The method .keys() of a variable dictionary allows to obtain the list of keys of the dictionary. For example

- -
-
-
-
- -
- -
-
- -
-
-
dictionary.keys()
-
- -
-
-
- -
-
- -
-
- - - -
-
dict_keys(['Kenia', 'Noruega', 'Finlandia', 'Rusia', 'Rio de Janeiro', 'Japón', 'Colorado', 'Alemania', 'Colombia'])
-
- -
-
-
-
- -
-
- -
- -
-
-

And the list of values:

- -
-
-
-
- -
- -
-
- -
-
-
dictionary.values()
-
- -
-
-
- -
-
- -
-
- - - -
-
dict_values(['Nairobi', 'Oslo', 'Helsinski', 'Moscú', 'Rio', 'Tokio', 'Denver', 'Berlin', 'Bogotá'])
-
- -
-
-
-
- -
-
- -
- -
-
-

For strings we have for example the conversion to lower case

- -
-
-
-
- -
- -
-
- -
-
-
"Juan Valdez".lower()
-
- -
-
-
- -
-
- -
-
- - - -
-
'juan valdez'
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
"juan valdez".title()
-
- -
-
-
- -
-
- -
-
- - - -
-
'Juan Valdez'
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
"juan valdez".upper()
-
- -
-
-
- -
-
- -
-
- - - -
-
'JUAN VALDEZ'
-
- -
-
-
-
- -
-
- -
- -
-
-

Attributes

-
-
-
-
- -
- -
-
- -
-
-
a=1j
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
a.imag
-
- -
-
-
- -
-
- -
-
- - - -
-
1.0
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
a.real
-
- -
-
-
- -
-
- -
-
- - - -
-
0.0
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
z=3+5j
-
- -
-
-
- -
-
- -
- -
-
-

with attributes

- -
-
-
-
- -
- -
-
- -
-
-
z.real
-
- -
-
-
- -
-
- -
-
- - - -
-
3.0
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
z.imag
-
- -
-
-
- -
-
- -
-
- - - -
-
5.0
-
- -
-
-
-
- -
-
- -
- -
-
-

and the method:

- -
-
-
-
- -
- -
-
- -
-
-
z.conjugate()
-
- -
-
-
- -
-
- -
-
- - - -
-
(3-5j)
-
- -
-
-
-
- -
-
- -
- -
-
-

In the notebook, All the methods and attributes of an object can be accessed by using the <TAB> key after write down the point:

-
variable.<TAB>
-
- -
-
-
-
- -
- -
-
- -
-
-
z.
-
- -
-
-
- -
-
- -
- -
-
-

Activity: Check the methods and attributes of the dictionary dictonary. HINT: Check the help for some of them by using a question mark, "?", at the end:

- -
variable.method?
- -
-
-
-
- -
- -
-
-

Unicode

Is an standard to encode characters. In Python 3, around 120.000 characters can be used to define variables. For example, one right to left arabic variable can be defined as

- -
-
-
-
- -
- -
-
- -
-
-
=2
-print('Arabic character values is: {}'.format())
-
- -
-
-
- -
-
- -
-
- -
-
Arabic character values is: 2
-
-
-
-
-
-
- -
-
- -
- -
-
-

Spanish example

- -
-
-
-
- -
- -
-
- -
-
-
mamá='Lola'
-
- -
-
-
- -
-
- -
- -
-
-

In Jupyter lab greek symbols can be accessed by using its LaTeX command follow by the <TAB> key.

-

\alpha+<TAB>=0.5 could convert on the fly to

- -
-
-
-
- -
- -
-
- -
-
-
α=0.5
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
print(α)
-
- -
-
-
- -
-
- -
-
- -
-
0.5
-
-
-
-
-
-
- -
-
- -
- -
-
-

Alternatively yuo can copy the character from some list of unicode symbols, like this one.

-

Activity: Define a Greek variable by using a symbol from the previous list

- -
-
-
-
- -
- -
-
-

Final remarks

Make your google Python questions in English and check specially the https://stackoverflow.com/ results.

-

Activity: Make some Python query in Google and paste the example code below

- -
-
-
-
- -
- -
-
- -
-
-
input('What was the Google query that you ask?:\n')
-
- -
-
-
- -
-
- -
- -
-
-

Sample code:

- -
-
-
-
- -
- -
-
-

Parallel

foo(x)  delayed(foo)(x)
-
- -
-
-
-
- -
- -
-
- -
-
-
>>> from joblib import Parallel, delayed
->>> from math import sqrt
->>> Parallel(n_jobs=8)(delayed(sqrt)(i**2) for i in range(10))
-
- -
-
-
- -
-
- -
-
- - - -
-
[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]
-
- -
-
-
-
- -
-
- - - - - - -
- \ No newline at end of file diff --git a/_build/features/scientific-libraries.html b/_build/features/scientific-libraries.html deleted file mode 100644 index ce21961..0000000 --- a/_build/features/scientific-libraries.html +++ /dev/null @@ -1,2580 +0,0 @@ ---- -interact_link: content/features/scientific-libraries.ipynb -kernel_name: python3 -kernel_path: content/features -has_widgets: false -title: |- - Scientific libraries -pagenum: 2 -prev_page: - url: /features/overview-python.html -next_page: - url: /features/Pandas.html -suffix: .ipynb -search: numpy scipy arrays python functions basic methods scientific libraries www x org import data lists linear algebra div com features different array pythonnumpy official name colab src advanced useful manipulating used object framework numerical abstractions loops sympy pages anaconda math miscellaneous space svg not supported capabilities operations implemented attributes level also only packages pandas tasks importing vs style float right markdown img integrate imported np reverse next logical course covered list research google very allows common task should its nevertheless extend nested new through algorithms code true must designed avoid high work intended system standard generic uses specific interested general - -comment: "***PROGRAMMATICALLY GENERATED, DO NOT EDIT. SEE ORIGINAL FILES IN /content***" ---- - -
-
Scientific libraries
-
-
- -
-
-

Scientific Libraries with Python

Open In Colab

-

Although coding with Python is very versatile and allows many advanced features that are useful when manipulating massive data (a common task in science), Python is still a multipurpose language, what implies that scientific routines and functions cannot (should not) be supported within its basic core. Nevertheless, there are many different scientific libraries that can extend the capabilities of Python to scientific implementations in a natural way. One of the most used libraries is NumPy. This introduce the array object as a generalization of Python nested lists. This new object has many linear algebra operations implemented as methods or attributes. This operations are implemented at the low level through fast highly optimized algorithms.

- -
-
-
-
- -
- -
-
-

Python+NumPy

In this way, Python+NumPy can be seen as a framework to implement numerical code as linear algebra abstractions which replaces the slow Python loops. The contrary is also true. In this framework each algorithm must be designed to try to avoid the use of Python loops like for or while.

-

An ideal program implemented in Python+NumPy does not have explicit Python loops, but only linear algebra abstractions.

- -
-
-
-
- -
- -
-
-

Extended Python+Numpy framework

All the other high level packages for scientific computation are designed to work around the linear algebra abstractions of the Python+NumPy framework

-
    -
  • Pandas add labels to the Numpy arrays.
  • -
  • Mathplotlib plotting library. Ti visualize arrays in 1, 2 and 3 dimensions
  • -
  • SciPy, intended for manipulating NumPy arrays more efficiently and for extending and including numerical methods, respectively.
  • -
-

Another less used libraries like SymPy are intended for manipulating analytical expressions, i.e. a CAS (Computer Algebraic System).

-

Installation of these libraries is often an easy task. In most of the Linux distros you should find them in the official repositories.

-

Avoid loops. Use abstractions

- -
-
-
-
- -
- -
-
-

Official Pages

See the official pages of the libraries for new versions, news and manuals.

-

NumPy:

-

http://www.numpy.org/

-

SciPy

-

http://www.scipy.org/

-

SymPy

-

http://www.sympy.org/

-

Anaconda

-

https://www.anaconda.com/

-

Anaconda is a self-cointained Python distribution that integrates many standard scientific libraries with Python, along with some generic libraries like MongoDB

-

There are many different scientific libraries for Python with many different uses, even for very specific tasks. However, as we are interested in general numerical methods, we will focus only on NumPy and Scipy.

- -
-
-
-
- - - -
- -
-
-
- -
-
-
-
- -
- -
-
-
- -

NumPy

NumPy is the fundamental package for scientific computing with Python. It contains among other things:

-
    -
  • a powerful N-dimensional array object
  • -
  • sophisticated (broadcasting) functions
  • -
  • tools for integrating C/C++ and Fortran code
  • -
  • useful linear algebra, Fourier transform, and random number capabilities
  • -
-

Besides its obvious scientific uses, NumPy can also be used as an efficient multi-dimensional container of generic data. Arbitrary data-types can be defined. This allows NumPy to seamlessly and speedily integrate with a wide variety of databases.

- -
-
-
-
- -
- -
-
-

Basic Use

Importing and basic math

NumPy can be imported in several different ways. Keeping the standard name space is the recommended way

- -
-
-
-
- -
- -
-
- -
-
-
#Importing NumPy with the alias of np (recommended)
-import numpy as np
-
- -
-
-
- -
-
- -
- -
-
-

The stantard name space for other Python modules are

-
import numpy as np
-import pandas as pd
-import scipy as sp
-import matplotlib.pyplot as plt
-import numpy.linalg as la
-import math as m # real 
-import cmath as cm # complex
-
- -
-
-
-
- -
- -
-
-

If imported through the name space np, NumPy methods and attributes are accessed by using the assigned name space.

-

The Basic methods of NumPy include the usual mathematical functions

- -
-
-
-
- -
- -
-
- -
-
-
print( np.exp(10.5), np.log(52.3), np.log10(63.9), np.sqrt(10.0) )
-
- -
-
-
- -
-
- -
-
- -
-
36315.502674246636 3.9569963710708773 1.8055008581584002 3.1622776601683795
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
#Trigonometric functions
-print (np.sin(5.0), np.cos(9.6), np.arcsin(0.5), np.arctan(5))
-
- -
-
-
- -
-
- -
-
- -
-
-0.9589242746631385 -0.984687855794127 0.5235987755982989 1.373400766945016
-
-
-
-
-
-
- -
-
- -
- -
-
-

The basic attributes include some important constants

- -
-
-
-
- -
- -
-
- -
-
-
print  ( "The value of PI is {:.6f}".format( np.pi ) )
-
- -
-
-
- -
-
- -
-
- -
-
The value of PI is 3.141593
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
print  ( "The value of e is {:.6f}".format( np.e ) )
-
- -
-
-
- -
-
- -
-
- -
-
The value of e is 2.718282
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
print  ( "∞={}".format( np.inf ) )
-
- -
-
-
- -
-
- -
-
- -
-
∞=inf
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
200000000<np.inf
-
- -
-
-
- -
-
- -
-
- - - -
-
True
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
print  ( "0/0={}".format( np.nan ) )
-
- -
-
-
- -
-
- -
-
- -
-
0/0=nan
-
-
-
-
-
-
- -
-
- -
- -
-
-

Conflicts without name spaces:

- -
-
-
-
- -
- -
-
- -
-
-
from numpy import *
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
sin([2,3])
-
- -
-
-
- -
-
- -
-
- - - -
-
array([0.90929743, 0.14112001])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
from math import *
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
sin([2,3])
-
- -
-
-
- -
-
- -
-
- -
-
----------------------------------------------------------------------------
-TypeError                                 Traceback (most recent call last)
-<ipython-input-17-0612cee6990d> in <module>
-----> 1 sin([2,3])
-
-TypeError: must be real number, not list
-
-
-
-
-
- -
-
- -
- -
-
-

Lists vs NumPy arrays

-
-
-
-
- -
- -
-
-

Supported methods for lists

- -
-
-
-
- -
- -
-
-

x.append x.count x.extend x.index x.insert x.pop x.remove x.reverse x.sort

- -
-
-
-
- -
- -
-
-

Supported methods for NumPy arrays

- -
-
-
-
- -
- -
-
- -
-
-
x.T             x.clip          x.dot           x.item          x.prod          x.setfield      x.take
-x.all           x.compress      x.dtype         x.itemset       x.ptp           x.setflags      x.tofile
-x.any           x.conj          x.dump          x.itemsize      x.put           x.shape         x.tolist
-x.argmax        x.conjugate     x.dumps         x.max           x.ravel         x.size          x.tostring
-x.argmin        x.copy          x.fill          x.mean          x.real          x.sort          x.trace
-x.argsort       x.ctypes        x.flags         x.min           x.repeat        x.squeeze       x.transpose
-x.astype        x.cumprod       x.flat          x.nbytes        x.reshape       x.std           x.var
-x.base          x.cumsum        x.flatten       x.ndim          x.resize        x.strides       x.view
-x.byteswap      x.data          x.getfield      x.newbyteorder  x.round         x.sum           
-x.choose        x.diagonal      x.imag          x.nonzero       x.searchsorted  x.swapaxes
-
- -
-
-
- -
-
- -
- -
-
-

In common

- -
-
-
-
- -
- -
-
- -
-
-
#Lists and numpy arrays can both store any type of data
-x1 = [1.2, 3.5, 1.9]
-x2 = np.array([1.6, -2.6, 6.9])
-print( x1, x2 )
-
- -
-
-
- -
-
- -
-
- -
-
[1.2, 3.5, 1.9] [ 1.6 -2.6  6.9]
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
type(x2)
-
- -
-
-
- -
-
- -
-
- - - -
-
numpy.ndarray
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#For lists, new elements can be added using append method
-x1 = [1.2, 3.5, 1.9]
-x1.append(5.9)
-
-#For arrays, new elements can be added using append function of NumPy
-x2 = np.array([1.6, -2.6, 6.9])
-x2 = np.append(x2,3)
-
-print (x1,x2)
-
- -
-
-
- -
-
- -
-
- -
-
[1.2, 3.5, 1.9, 5.9] [ 1.6 -2.6  6.9  3. ]
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
#A list can be converted into a numpy array
-x = [1.1,3.4,1.0]
-x = np.array(x)
-#And a numpy array into a list as well
-x = list(x)
-
- -
-
-
- -
-
- -
- -
-
-

Differences

- -
-
-
-
- -
- -
-
- -
-
-
#Operator + for lists is overloaded for concatenating 
-x1 = [1,2,3]
-x2 = [3,2,1]
-print (x1+x2)
-
- -
-
-
- -
-
- -
-
- -
-
[1, 2, 3, 3, 2, 1]
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
#Operator + for numpy arrays is overloaded for adding
-x1 = np.array([1,2,3])
-x2 = np.array([3,2,1])
-print (x1+x2)
-
- -
-
-
- -
-
- -
-
- -
-
[4 4 4]
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
#Lists do not support other operators
-x1 = [1.2,4.8,6.9]
-x2 = [2.6,2.8,1.1]
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
#Multiplication
-print x1*x2
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
#Division
-print x1/x2
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
#Subtraction
-print x1-x2
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
#Power
-print x1**x2
-
- -
-
-
- -
-
- -
- -
-
-

NumPy arrays

- -
-
-
-
- -
- -
-
- -
-
-
#Numpy arrays support any mathematical operation (element by element)
-x1 = np.array([1.2,4.8,6.9])
-x2 = np.array([2.6,2.8,1.1])
-
-print ("Adding", x1+x2)
-print ("Multiplication", x1*x2)
-print ("Division", x1/x2)
-print ("Subtraction", x1-x2)
-print ("Power", x1**x2)
-
- -
-
-
- -
-
- -
-
- -
-
Adding [3.8 7.6 8. ]
-Multiplication [ 3.12 13.44  7.59]
-Division [0.46153846 1.71428571 6.27272727]
-Subtraction [-1.4  2.   5.8]
-Power [ 1.6064649  80.81192733  8.37016462]
-
-
-
-
-
-
- -
-
- -
- -
-
-

Note: Matrices can be represented as NumPy arrays where each element is a row vector. Nevertheless, be careful when multiply arrays, the operator * is overloaded in such a way that single elements are multiplied one by one, quite different from multiplication of matrices.

- -
-
-
-
- -
- -
-
- -
-
-
A = np.array([[1,2],[3,4]])
-B = np.array([[4,3],[2,1]])
-print ('A=\n{}'.format(A)) 
-print ('B=\n{}'.format(B))
-print ('A*B=\n{}'.format(A*B)) # No matrix multiplication
-
- -
-
-
- -
-
- -
-
- -
-
A=
-[[1 2]
- [3 4]]
-B=
-[[4 3]
- [2 1]]
-A*B=
-[[4 6]
- [6 4]]
-
-
-
-
-
-
- -
-
- -
- -
-
-

A matrix element can be accessed directly

- -
-
-
-
- -
- -
-
- -
-
-
A[0,1]
-
- -
-
-
- -
-
- -
-
- - - -
-
2
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
A[0][1]
-
- -
-
-
- -
-
- -
-
- - - -
-
2
-
- -
-
-
-
- -
-
- -
- -
-
-

Advanced features of arrays

-
-
-
-
- -
- -
-
-

NumPy arrays have a number of interesting features that facilitate complex tasks. Next it is shown some of the more useful ones.

- -
-
-
-
- -
- -
-
-

Masks

Superspostion of a logical array unpon the original one. The output filters only the True values

- -
-
-
-
- -
- -
-
- -
-
-
#It is possible to access elements of a numpy array using booleans
-x = np.array([1,2,3,4])
-y = np.array([False, False, True, True])
-x[y]
-
- -
-
-
- -
-
- -
-
- - - -
-
array([3, 4])
-
- -
-
-
-
- -
-
- -
- -
-
-

Automatic creation of masks

- -
-
-
-
- -
- -
-
- -
-
-
x>2
-
- -
-
-
- -
-
- -
-
- - - -
-
array([False, False,  True,  True])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
x[x>2] # Automatic mask implementation
-
- -
-
-
- -
-
- -
-
- - - -
-
array([3, 4])
-
- -
-
-
-
- -
-
- -
- -
-
-

which is much better and faster than:

- -
-
-
-
- -
- -
-
- -
-
-
xfin=[]
-for i in x:
-    if i>2:
-        xfin.append(i)
-        
-xfin=np.array(xfin)
-xfin
-
- -
-
-
- -
-
- -
-
- - - -
-
array([3, 4])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#Operators >, <, >=, <= and == are also overloaded for numpy arrays
-x = np.array([0,5,8,0])
-y = np.array([0,6,5,1])
-print(x>y) 
-print(x<y) 
-print(x==y) 
-print(x>4) 
-
- -
-
-
- -
-
- -
-
- -
-
[False False  True False]
-[False  True False  True]
-[ True False False False]
-[False  True  True False]
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
#Combining these features, we can perform searches and comparisons far more efficient
-x = np.array([1,4,2,6,8,4,3,0,9,1,3,6,7])
-#A new list with numbers greater than 4
-x[x>=4]
-
- -
-
-
- -
-
- -
-
- - - -
-
array([4, 6, 8, 4, 9, 6, 7])
-
- -
-
-
-
- -
-
- -
- -
-
-

Numpy has logical operators: np.logical_...

-

For array([1,4,2,6,8,4,3,0,9,1,3,6,7]):

- -
-
-
-
- -
- -
-
- -
-
-
x[ np.logical_and(x>2, x<6) ]
-
- -
-
-
- -
-
- -
-
- - - -
-
array([4, 4, 3, 3])
-
- -
-
-
-
- -
-
- -
- -
-
-

or

- -
-
-
-
- -
- -
-
- -
-
-
x[ (x>2) & (x<6) ] #or: |
-
- -
-
-
- -
-
- -
-
- - - -
-
array([4, 4, 3, 3])
-
- -
-
-
-
- -
-
- -
- -
-
-

the full mask can be negated!

-

For array([1,4,2,6,8,4,3,0,9,1,3,6,7]):

- -
-
-
-
- -
- -
-
- -
-
-
x[~((x>2) & (x<6)) ]
-
- -
-
-
- -
-
- -
-
- - - -
-
array([1, 2, 6, 8, 0, 9, 1, 6, 7])
-
- -
-
-
-
- -
-
- -
- -
-
-

Numpy methods to basic calculations

spreadsheeet like operations

- -
-
-
-
- -
- -
-
- -
-
-
#Native methods of numpy arrays allow to calculate basic quantities
-x = np.array([1,4,2,6,8,4,3,0,9,1,3,6,7])
-#Maximum element
-print( "Maximum element", x.max() )
-#Minimum element
-print( "Minimum element", x.min())
-#Mean value
-"Mean value", x.mean()
-
- -
-
-
- -
-
- -
-
- -
-
Maximum element 9
-Minimum element 0
-
-
-
-
-
-
- - - -
-
('Mean value', 4.153846153846154)
-
- -
-
-
-
- -
-
- -
- -
-
-

upon the indices

-
-
-
-
- -
- -
-
- -
-
-
print(x)
-
- -
-
-
- -
-
- -
-
- -
-
[1 4 2 6 8 4 3 0 9 1 3 6 7]
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
#Sorted arguments of the array
-print ("Sorted arguments", x.argsort() )
-#Sorted array
-print ( "Sorted array", x[x.argsort()])
-
- -
-
-
- -
-
- -
-
- -
-
Sorted arguments [ 7  0  9  2  6 10  1  5  3 11 12  4  8]
-Sorted array [0 1 1 2 3 3 4 4 6 6 7 8 9]
-
-
-
-
-
-
- -
-
- -
- -
-
-

Direct sorted

- -
-
-
-
- -
- -
-
- -
-
-
x = np.array([1,4,2,6,8,4,3,0,9,1,3,6,7])
-x.sort()
-x
-
- -
-
-
- -
-
- -
-
- - - -
-
array([0, 1, 1, 2, 3, 3, 4, 4, 6, 6, 7, 8, 9])
-
- -
-
-
-
- -
-
- -
-or -
- -
- -
-
- -
-
-
x = np.array([1,4,2,6,8,4,3,0,9,1,3,6,7])
-np.sort( x )
-
- -
-
-
- -
-
- -
-
- - - -
-
array([0, 1, 1, 2, 3, 3, 4, 4, 6, 6, 7, 8, 9])
-
- -
-
-
-
- -
-
- -
- -
-
-

Miscellaneous methods

-
-
-
-
- -
- -
-
-

NumPy includes many general purpose functions that complement the capabilities of python. We are interested here specially in functions for creating ordered arrays, storing and loading data as well as histograms, tasks that will be continuously required for the activities of the course.

- -
-
-
-
- -
- -
-
- -
-
-
#Create an array of 1's with a given size (even 2D sizes)
-x = np.ones(5)
-x
-
- -
-
-
- -
-
- -
-
- - - -
-
array([1., 1., 1., 1., 1.])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#Create an array of zeros with a given size (even 2D sizes)
-x = np.zeros( (2,5) )
-x
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[0., 0., 0., 0., 0.],
-       [0., 0., 0., 0., 0.]])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
import numpy as np
-x=np.array([4,7,4,6,9])
-x.sum()
-
- -
-
-
- -
-
- -
-
- - - -
-
30
-
- -
-
-
-
- -
-
- -
- -
-
-

Miscellaneous functions

-
-
-
-
- -
- -
-
- -
-
-
#Create an array with a given range and a number of intervals
-x = np.linspace( -np.pi, np.pi, 10 ) 
-print (x)
-
- -
-
-
- -
-
- -
-
- -
-
[-3.14159265 -2.44346095 -1.74532925 -1.04719755 -0.34906585  0.34906585
-  1.04719755  1.74532925  2.44346095  3.14159265]
-
-
-
-
-
-
- -
-
- -
- -
-
-

For arrays that expands more than one order of magnitud, use

- -
-
-
-
- -
- -
-
- -
-
-
np.logspace( np.log10(2), np.log10(50000),10        )
-
- -
-
-
- -
-
- -
-
- - - -
-
array([2.00000000e+00, 6.16155028e+00, 1.89823509e+01, 5.84803548e+01,
-       1.80164823e+02, 5.55047308e+02, 1.70997595e+03, 5.26805138e+03,
-       1.62296817e+04, 5.00000000e+04])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
np.linspace( 2, 50000,10        )
-
- -
-
-
- -
-
- -
-
- - - -
-
array([2.00000000e+00, 5.55733333e+03, 1.11126667e+04, 1.66680000e+04,
-       2.22233333e+04, 2.77786667e+04, 3.33340000e+04, 3.88893333e+04,
-       4.44446667e+04, 5.00000000e+04])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
#Create an array with a given range and a given step
-x = np.arange( 1, 5, 0.2 )
-print( x )
-
- -
-
-
- -
-
- -
-
- -
-
[1.  1.2 1.4 1.6 1.8 2.  2.2 2.4 2.6 2.8 3.  3.2 3.4 3.6 3.8 4.  4.2 4.4
- 4.6 4.8]
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
#Using the function savetxt, it is possible to store data from a numpy array
-data = np.array([[3.2, 2.1],[3.1, 4.1]])
-np.savetxt( "file.dat", data, fmt="%1.5e  %1.5e" )
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
cat file.dat
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
#In the same way, using the function loadtxt it is possible to load external data files
-data = np.loadtxt("file.dat")
-#Data is then a multidimensional array with the loaded data
-print( data )
-
- -
-
-
- -
-
- -
- -
-
-

Other useful functions will be covered when needed during the course.

- -
-
-
-
- -
- -
-
-

List Slices

Slices work on list-like objects like numpy arrays, and can also be used to change sub-parts of the list.

- -
-
-
-
- -
- -
-
- -
-
-
x=np.ones(10)
-x[1:3]=2
-x[-1]=8
-x[-3:-1]=6
-x
-
- -
-
-
- -
-
- -
-
- - - -
-
array([1., 2., 2., 1., 1., 1., 1., 6., 6., 8.])
-
- -
-
-
-
- -
-
- -
- -
-
-

Reverse order (arrays do not have the reverse() method)

- -
-
-
-
- -
- -
-
- -
-
-
x[::-1]
-
- -
-
-
- -
-
- -
-
- - - -
-
array([8., 6., 6., 1., 1., 1., 1., 2., 2., 1.])
-
- -
-
-
-
- -
-
- -
- -
-
-
- -

Pandas

-
-
-
-
- -
- -
-
- -
-
-
numbers={"even": [0,2,4,6,8],   #  First  key-list
-         "odd" : [1,3,5,7,9] }  #  Second key-list
-
-import pandas as pd
-pd.set_option('display.max_colwidth',200)
-df=pd.DataFrame(numbers)
-df
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
evenodd
001
123
245
367
489
-
-
- -
-
-
-
- -
-
- -
- -
-
-

In the previous DataFrame, all the column values are converted to Numpy arrays, which is the basic object in Numpy corresponding to generalized nested lists;

- -
-
-
-
- -
- -
-
- -
-
-
df.even
-
- -
-
-
- -
-
- -
-
- - - -
-
0    0
-1    2
-2    4
-3    6
-4    8
-Name: even, dtype: int64
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
df.even.values
-
- -
-
-
- -
-
- -
-
- - - -
-
array([0, 2, 4, 6, 8])
-
- -
-
-
-
- -
-
- -
- -
-
-
- -

SciPy

-
-
-
-
- -
- -
-
-

SciPy is a collection of mathematical algorithms and convenience functions built on the Numpy extension of Python. It adds significant power to the interactive Python session by providing the user with high-level commands and classes for manipulating and visualizing data. With SciPy an interactive Python session becomes a data-processing and system-prototyping environment rivaling sytems such as MATLAB, IDL, Octave, R-Lab, and SciLab.

-

Some of the packages included with SciPy are:

-
    -
  • Special functions (scipy.special)
  • -
  • Integration (scipy.integrate)
  • -
  • Optimization (scipy.optimize)
  • -
  • Interpolation (scipy.interpolate)
  • -
  • Fourier Transforms (scipy.fftpack)
  • -
  • Signal Processing (scipy.signal)
  • -
  • Linear Algebra (scipy.linalg)
  • -
- -
-
-
-
- -
- -
-
-

Each of these packages must be imported separately.

- -
-
-
-
- -
- -
-
- -
-
-
#Importing integrate package
-import scipy.integrate as integ
-
- -
-
-
- -
-
- -
- -
-
-

The integrate package then includes the next functions:

- -
-
-
-
- -
- -
-
- -
-
-
integ.Tester        integ.fixed_quad    integ.odepack       integ.quadrature    integ.test          
-integ.complex_ode   integ.newton_cotes  integ.quad          integ.romb          integ.tplquad       
-integ.cumtrapz      integ.ode           integ.quad_explain  integ.romberg       integ.trapz         
-integ.dblquad       integ.odeint        integ.quadpack      integ.simps         integ.vode  
-
- -
-
-
- -
-
- -
- -
-
-

Almost each of the numerical methods that will be covered during the course can be found in SciPy. In next classes we will explore the offered options by SciPy according to the specific methods covered.

- -
-
-
-
- -
- -
-
- -
-
-
name='Diego'
-print(f"{name} {name} {name}")
-
- -
-
-
- -
-
- -
-
- -
-
Diego Diego Diego
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
'{} {} {}'.format(name,name,name)
-
- -
-
-
- -
-
- -
-
- - - -
-
'Diego Diego Diego'
-
- -
-
-
-
- -
-
- - - - -
- \ No newline at end of file diff --git a/_build/features/statistics.html b/_build/features/statistics.html deleted file mode 100644 index 6e1c83d..0000000 --- a/_build/features/statistics.html +++ /dev/null @@ -1,2839 +0,0 @@ ---- -interact_link: content/features/statistics.ipynb -kernel_name: python3 -kernel_path: content/features -has_widgets: false -title: |- - Statistics -pagenum: 25 -prev_page: - url: /features/medium_modelling_part_one.html -next_page: - url: /features/Intro_clases.html -suffix: .ipynb -search: m sum xi yi random n e align frac data scipy left font right error least numbers xiyi com linear function polynomial begin end x square example partial color red not set using order approximation adjust html points functions going used value f where optimize parameters activity decay github also necessary numpy take obtained procedure coefficients generated fit initial following generate seed colab restrepo squares non fitting associated known equations curve docs starting c between wi drag d b google computationalmethods blob master material ipynb src only why raw stackoverflow given build certain axi minimize since solve resulting second org - -comment: "***PROGRAMMATICALLY GENERATED, DO NOT EDIT. SEE ORIGINAL FILES IN /content***" ---- - -
-
Statistics
-
-
- -
-
-

Open In Colab

- -
-
-
-
- -
- -
-
-

Statistics

-
-
-
-
- -
- -
-
-

Considering the amount of data produced nowadays in many fields, the computer manipulation of this information is not only important but also has become a very active field of study. Despite of the fact of increasing computational facilities, the effort necessary to make statistical analysis has become more complicated, at least in the computational aspect. This is why -becomes fundamental to some aspects, leastwise in a raw way.

- -
-
-
-
- - - -
- -
-
- -
-
-
%pylab inline
-
- -
-
-
- -
-
- -
-
- -
-
Populating the interactive namespace from numpy and matplotlib
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
import numpy as np
-from matplotlib import animation
-
- -
-
-
- -
-
- - - -
- -
-
-

Given a data set, the first approach to find a function that passes through the points would be using a -interpolation polynomial. But we should take special attention to the way data set is gathered, i.e., usually -is a sample obtained experimentally or in a way that has associated an intrinsic error. -Then, forcing that the approximate function passes through all the points would actually incur in incrementing the error. This is why it is necessary to build a different procedure to build the function that fits the data.

-

The fitting functions, though, are build using a Lagrange polynomial and the order of this polynomial constitutes -the approximation that is going to be used. But the fitting function is not going to take the exact value in -the known points, they are going to desagree in certain tolerance value.

- -
-
-
-
- -
- -
-
-

Linear least squares

-
-
-
-
- -
- -
-
-

Approximating a data set to a linear Langrange polynomial would be just to use -$$ -y_i= f(x_i) = a_1x_i + a_0\,. -$$ -However, with experimental data, the problem is that the values $y_i$ are not precise, then it is proposed to find the best approximation. -For the best linear approximation, we need to find for all points the value of $a_0$ and $a_1$ that minimize the error -$$ -E = E(a_0,a_1) = \sum_{i=1}^{m}[y_i - (a_1 x_i + a_0)]^2 -$$ -where the square is more well suited for the minimization procedure since avoids the fluctions for changes of sign.

-

To minimize the function of 2 variables, $E(a_0,a_1)$ with respect to $a_0$ and $a_1$, it is necessary to set its partial derivatives to zero and simultaneously -solve to the resulting equations.

-

To establish the minimzation equations, it is necesary to take the partial derivatives with respect to $a_0$ and $a_1$ and and equal them to zero -$$ -\frac{\partial E}{\partial a_0} = 0\,, \hspace{1cm} -\frac{\partial E}{\partial a_1} = 0\,. -$$

-

Afterwards,

-\begin{align} -&0= 2\sum_{i=1}^{m}(y_i -a_1x_i-a_0)(-1)\,, && -&0 =& 2\sum_{i=1}^{m}(y_i -a_1x_i-a_0)(-x_i) \\ -&a_0 m + a_1\sum_{i=1}^{m}x_i = \sum_{i=1}^{m} y_i\,,&& &a_0\sum_{i=1}^{m}x_i + a_1\sum_{i=1}^{m}x_i^2 = \sum_{i=1}^{m} x_iy_i -\end{align}\begin{align} -a_0= &\frac{ \sum_{i=1}^{m} y_i-a_1\sum_{i=1}^{m}x_i }{m} -\end{align} -
-
-
-
- -
- -
-
-

Replacing back in the second equation -\begin{align} - \left( \frac{ \sum_{i=1}^{m} y_i-a_1\sum_{i=1}^{m}x_i }{m} \right)\sum_{i=1}^{m}x_i + a_1\sum_{i=1}^{m}x_i^2 = \sum_{i=1}^{m} x_iy_i -\end{align} -\begin{align} - \frac{1}{m}\sum_{i=1}^{m} y_i \sum_{i=1}^{m}x_i -a_1\frac{1}{m} \sum_{i=1}^{m}x_i \sum_{i=1}^{m}x_i + a_1\sum_{i=1}^{m}x_i^2 = \sum_{i=1}^{m} x_iy_i -\end{align} -\begin{align} - a_1\left[ \sum_{i=1}^{m}x_i^2 -\frac{1}{m}\left( \sum_{i=1}^{m}x_i \right)^2 \right] = \sum_{i=1}^{m} x_iy_i - \frac{1}{m}\sum_{i=1}^{m} y_i \sum_{i=1}^{m}x_i -\end{align} -\begin{align} - a_1\left[ m\sum_{i=1}^{m}x_i^2 -\left( \sum_{i=1}^{m}x_i \right)^2 \right] = m\sum_{i=1}^{m} x_iy_i -\sum_{i=1}^{m} y_i \sum_{i=1}^{m}x_i -\end{align}

- -
-
-
-
- -
- -
-
-

Therefore -\begin{align} -a_1 = \frac{m\sum_{i=1}^{m} x_iy_i - \sum_{i=1}^{m} x_i \sum_{i=1}^{m} y_i } -{m\sum_{i=1}^{m} x_i^2 - \left(\sum_{i=1}^{m} x_i\right)^2} -\end{align}

- -
-
-
-
- -
- -
-
-

Replacing back in $a_0$ -\begin{align} -ma_0= &\sum_{i=1}^{m} y_i-a_1\sum_{i=1}^{m}x_i \\ - = &\sum_{i=1}^{m} y_i-\left[\frac{m\sum_{i=1}^{m} x_iy_i - \sum_{i=1}^{m} x_i \sum_{i=1}^{m} y_i } -{m\sum_{i=1}^{m} x_i^2 - \left(\sum_{i=1}^{m} x_i\right)^2} \right]\sum_{i=1}^{m}x_i \\ -= &\sum_{i=1}^{m} y_i-\frac{m\sum_{i=1}^{m}x_i\sum_{i=1}^{m} x_iy_i - \left( \sum_{i=1}^{m} x_i\right)^2 \sum_{i=1}^{m} y_i } -{m\sum_{i=1}^{m} x_i^2 - \left(\sum_{i=1}^{m} x_i\right)^2} \\ -= &\frac{m\sum_{i=1}^{m} x_i^2\sum_{i=1}^{m} y_i-m\sum_{i=1}^{m}x_i\sum_{i=1}^{m} x_iy_i } -{m\sum_{i=1}^{m} x_i^2 - \left(\sum_{i=1}^{m} x_i\right)^2} \\ -\end{align}

- -
-
-
-
- -
- -
-
-\begin{align} -a_0= &\frac{\sum_{i=1}^{m} x_i^2\sum_{i=1}^{m} y_i-\sum_{i=1}^{m}x_i\sum_{i=1}^{m} x_iy_i } -{m\sum_{i=1}^{m} x_i^2 - \left(\sum_{i=1}^{m} x_i\right)^2} \\ -\end{align} -
-
-
-
- -
- -
-
-

where the coefficients $a_0$ and $a_1$ can be easily obtained

-$$ -a_0 = \frac{\sum_{i=1}^{m} x_i^2\sum_{i=1}^{m}y_i - \sum_{i=1}^{m} x_iy_i \sum_{i=1}^{m} x_i } -{m\sum_{i=1}^{m} x_i^2 - \left(\sum_{i=1}^{m} x_i\right)^2}\,, \hspace{1.5cm} -a_1 = \frac{m\sum_{i=1}^{m} x_iy_i - \sum_{i=1}^{m} x_i \sum_{i=1}^{m} y_i } -{m\sum_{i=1}^{m} x_i^2 - \left(\sum_{i=1}^{m} x_i\right)^2} -$$

Now, using the error definition one can find the error associated to the approximation made,

-

since the coefficients $a_0$ and $a_1$ are already known.

- -
-
-
-
- -
- -
-
-

From Least sqaure method in python:

-

There are many curve fitting functions in scipy and numpy and each is used differently, e.g. scipy.optimize.leastsq and scipy.optimize.least_squares. For simplicity, we will use scipy.optimize.curve_fit, but it is difficult to find an optimized regression curve without selecting reasonable starting parameters. A simple technique will later be demonstrated on selecting starting parameters.

-
-

In our first example the starting parameters will be just zeros

- -
-
-
-
- -
- -
-
-

Example 1

-
-
-
-
- -
- -
-
-

A body is moving under the influence of an external force, the variation of the position measured for different -times are compiled in table 1

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
t(s)x(m)v(m/s)
02.7633.10
1.1129.6621.33
2.2246.8316.57
3.3344.08-5.04
4.4437.26-11.74
5.5512.03-27.32
- -
-
-
-
- -
- -
-
- -
-
-
import pandas as pd
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
#'x': [2.76,  29.66,46.83,44.08,37.26,12.03],
-df=pd.DataFrame( {'t': [ 0.,  1.11,  2.22,  3.33,  4.44, 5.55],#'x': [2.76,  29.66,46.83,44.08,37.26,12.03],
-                  'v': [33.10, 21.33, 16.57, -5.04, -11.74, -27.32]} )
-df[['t','v']]
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
tv
00.0033.10
11.1121.33
22.2216.57
33.33-5.04
44.44-11.74
55.55-27.32
-
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
plt.plot(df.t,df.v,'ro')
-plt.xlabel('$t$ [s]',size=15 )
-plt.ylabel('$v$ [m/s]',size=15 )
-plt.grid()
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
import scipy.optimize as optimize
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
def func(t,a1,a0):
-    return a1*t+a0
-
- -
-
-
- -
-
- -
- -
-
-

The starting point is optional

- -
-
-
-
- -
- -
-
- -
-
-
starting_parameters=[0,0]
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
a,Δa=optimize.curve_fit(func,df.t,df.v,p0=starting_parameters)
-
- -
-
-
- -
-
- -
- -
-
-

The correlation matrix,$\Delta a$ , give as the error in the determination of the parameters

- -
-
-
-
- -
- -
-
- -
-
-
print(a)
-print('-'*20)
-print(Δa)
-σ = np.sqrt(np.diag(Δa))
-print('-'*20)
-print('a1={:.2f}±{:.2f}, a0={:.2f}±{:.2f}'.format(a[0],σ[0],a[1],σ[1]) )
-
- -
-
-
- -
-
- -
-
- -
-
[-10.88597169  34.69190478]
---------------------
-[[ 0.68398817 -1.89806718]
- [-1.89806718  7.72513347]]
---------------------
-a1=-10.89±0.83, a0=34.69±2.78
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
t_lin=np.linspace(0,5.55)
-v_model=func(t_lin,*a)
-df['v_fitted']=func(df.t,*a)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
df
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
tvv_fitted
00.0033.1034.691905
11.1121.3322.608476
22.2216.5710.525048
33.33-5.04-1.558381
44.44-11.74-13.641810
55.55-27.32-25.725238
-
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
plt.plot(df.t,df.v,'b.',label='exp. data')
-plt.plot(df.t,a[0]*df.t+a[1],'g-',lw=2,label="Linear adjust")
-for i in range(df.t.size):
-    plt.plot(np.array([df.t[i],df.t[i]]), np.array([df.v[i],df.v_fitted[i] ]),"c-")
-    
-plt.xlabel( "$t$ [s]", fontsize = 18 )
-plt.ylabel( "$v$  [m/s]", fontsize = 18 )
-plt.title("Linear data adjust")
-plt.legend()
-plt.grid()    
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-
- -
- -
-
-

Activity: Solve the problem with fmin_powell for the fit only (not the error correlation matrix) -$$ -E = E(a_0,a_1) = \sum_{i=1}^{m}[y_i - (a_1 x_i + a_0)]^2 -$$

-

Solution: -Let a=[a_0,a_1]

- -
-
-
-
- -
- -
-
- -
-
-
def E(a,x=df.t.values,y=df.v.values):
-    return ((y-(a[1]*x+a[0]))**2).sum()
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
E([1,0])
-
- -
-
-
- -
-
- -
-
- - - -
-
2686.9554000000003
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
E([2,1])
-
- -
-
-
- -
-
- -
-
- - - -
-
3105.6670999999997
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
E([33,-10])
-
- -
-
-
- -
-
- -
-
- - - -
-
79.44340000000005
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
def Ea0(x,a1=-10):
-    EE=[]
-    for a0 in x:
-        EE.append( E([a0,a1]))
-    return np.array(EE)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
Ea0([2,3])
-
- -
-
-
- -
-
- -
-
- - - -
-
array([5560.2434, 5203.4434])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
a0=np.linspace(10,50)
-plt.plot(a0,Ea0(a0,-10))
-
- -
-
-
- -
-
- -
-
- - - -
-
[<matplotlib.lines.Line2D at 0x7fd10f5e52b0>]
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
optimize.fmin_powell(E,[0,0],full_output=True)
-
- -
-
-
- -
-
- -
-
- -
-
Optimization terminated successfully.
-         Current function value: 58.991928
-         Iterations: 5
-         Function evaluations: 169
-
-
-
-
-
-
- - - -
-
(array([ 34.69190471, -10.88597167]),
- 58.99192761904762,
- array([[ 9.58580558, -2.62474386],
-        [ 0.03589244,  0.0271459 ]]),
- 5,
- 169,
- 0)
-
- -
-
-
-
- -
-
- -
- -
-
-

How does this work:

From Leat sqaure method in python:

-

curve_fit is one of many optimization functions offered by scipy. Given an initial value, the resulting estimated parameters are iteratively refined so that the resulting curve minimizes the residual error, or difference between the fitted line and sampling data. A better guess reduces the number of iterations and speeds up the result. With these estimated parameters for the fitted curve, one can now calculate the specific coefficients for a particular equation (a final exercise left to the OP).

-
- -
-
-
-
- -
- -
-
- -
-
-
# Finding adjusting parameters 
-def Linear_least_square( x,y ):
-    
-    #Finding coefficients 
-    length = len(x)
-    square_x = np.sum([x[i]**2 for i in xrange(length)])
-    sum_xy = np.sum([x[i]*y[i] for i in xrange(length)])
-    sum_x = np.sum(x)
-    sum_y = np.sum(y)
-    a0 = ( square_x*sum_y - sum_xy*sum_x ) / ( length*square_x  - sum_x**2 )
-    a1 = ( length*sum_xy - sum_x*sum_y ) / ( length*square_x  - sum_x**2 )
-    
-    #Returning a_0 and a_1 coefficients
-    return np.array([a0,a1])
-
-#Line function adjusting the data set
-def Line(a0,a1,x):
-    return a0+a1*x
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
xrange=range
-#========================================================
-# Adjusting to a first order polynomy the data set v 
-#========================================================
-#Setting figure
-plt.figure( figsize = (8,5) )
-
-#Time
-t = np.array([ 0.,  1.11,  2.22,  3.33,  4.44, 5.55])
-
-#Velocities measured for every time t[i]
-v = np.array([33.10, 21.33, 16.57, -5.04, -11.74, -27.32])
-
-#Making data adjust
-a0, a1 = Linear_least_square( t,v )
-
-#Finding error associated to linear approximation
-E = np.sum([ ( v[i] - Line(a0,a1,t[i]) )**2  for i in xrange(len(t))])
-
-#Plotting solution
-plt.plot( t, Line(a0,a1,t), ".-", lw = 3.,color = "green",label="Lineal adjust" )
-plt.plot( t, v, ".",color = "blue", label = "Data set" )
-for i in xrange(len(t)):
-    plt.plot(np.array([t[i],t[i]]), np.array([v[i],Line(a0,a1,t[i])]),"c-")
-    
-#Format of figure
-plt.xlabel( "$t(s)$", fontsize = 18 )
-plt.ylabel( "$v(m/s)$", fontsize = 18 )
-plt.xlim( (t[0], t[-1]) )
-plt.ylim( (v[-1], v[0]) )
-plt.title("Linear data adjust with error %f"%E)
-plt.legend()
-plt.grid(1)
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- - - -
- -
-
-

-Using the next data set of a spring mass system, find the lineal adjust. -

-

- -
-
-
-
- -
- -
-
-

Non-linear least square

-
-
-
-
- -
- -
-
-

In general, it can be used any polynomial order to adjust a data set, since it is satisfied that $n<m-1$, -with n the order of the polynomial and m the number of points known. Then, we have -$$ -P_n(x) = a_nx^n + a_{n-1}x^{n-1}+...+a_1x+a_0 -$$

-

Using a similar procedure followed in linear least square approximation, it is chose the constants $a_0,...a_n$ to minimize -the least square error

-$$ -E = \sum_{i=1}^{m} ( y_i - P_n(x_i) )^2 -= \sum_{i=1}^{m} ( y_i - \sum_{j=0}^{n}a_jx_i^j )^2 -$$

Expanding the square difference and taking into account that E to be minimized requires that $\partial E/ -\partial a_j = 0 $ for each $j=0,1,...n$. Following these arguments, it is found that the n+1 equations needed -to solve to find the coefficients $a_j$ are

-$$ -\sum_{k=0}^{n} a_k \sum_{i=1}^{m}x_i^{j+k} = \sum_{i=1}^{m}y_ix_i^j -$$

for each $j=0,1,...n$. A better way to show the equations, where m is the data length and n is the polynomial -order, is

-$$ -a_0\sum_{i=1}^{m}x_i^0 + a_1\sum_{i=1}^{m}x_i^1 + a_2\sum_{i=1}^{m}x_i^2 + ... + a_n\sum_{i=1}^{m}x_i^n = \sum_{i=1}^{m}y_i x_i^0 \\ -a_0\sum_{i=1}^{m}x_i^1 + a_1\sum_{i=1}^{m}x_i^2 + a_2\sum_{i=1}^{m}x_i^3 + ... + a_n\sum_{i=1}^{m}x_i^{n+1} = \sum_{i=1}^{m}y_i x_i^1\\ -\dotsc \\ -a_0\sum_{i=1}^{m}x_i^n + a_1\sum_{i=1}^{m}x_i^{n+1} + a_2\sum_{i=1}^{m}x_i^{n+2} + ... + a_n\sum_{i=1}^{m}x_i^{2n} = \sum_{i=1}^{m}y_i x_i^n -$$

Again, the error associated to the approximation can be obtained by initial definition of E. The error can also be defined -using a weight function $W_i$ as

-$$ -E = \sum_{i=1}^{m} W_i( y_i - P_n(x_i) )^2 -$$

this function $W_i$ can be defined in several ways. If $W_i = \sigma_i$, i.e., the standard deviation per particle, it is necessary to know the probability distribution followed by the experiments. In these cases where it is not known, -it is usually taken as one.

- -
-
-
-
- -
- -
-
-

**Activity**

-
-
-
-
- -
- -
-
-

-Adjust the position column data in the table 1 to a second order polynomial. What is the acceleration suffered -by the body? -

- -
-
-
-
- -
- -
-
- -
-
-
def func(t,a2,a1,a0):
-    return a2*t**2+a1*t+a0
-a,kk=optimize.curve_fit(func,df.t,df.v)
-t_lin=np.linspace(0,5.55)
-v2_model=func(t_lin,*a)
-df['v2_fitted']=func(df.t,*a)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
df
-
- -
-
-
- -
-
- -
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
tvv_fittedv2_fitted
00.0033.1034.69190533.096072
11.1121.3322.60847622.927643
22.2216.5710.52504811.801714
33.33-5.04-1.558381-0.281715
44.44-11.74-13.641810-13.322643
55.55-27.32-25.725238-27.321071
-
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
plt.plot(df.t,df.v,'b.',label='exp. data')
-plt.plot(t_lin,v_model,'g-',lw=2,label="Linear adjust")
-plt.plot(t_lin,v2_model,'r--',lw=2,label="quadratic adjust")
-for i in range(df.t.size):
-    plt.plot(np.array([df.t[i],df.t[i]]), np.array([df.v[i],df.v_fitted[i] ]),"c-")
-    
-plt.xlabel( "$t$ [s]", fontsize = 18 )
-plt.ylabel( "$v$  [m/s]", fontsize = 18 )
-plt.title("Linear data adjust")
-plt.legend()
-plt.grid(1)    
-
- -
-
-
- -
-
- -
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

**Activity**

-
-
-
-
- -
- -
-
-

-The air drag for a sphere that is moving at high speeds can be expresed in the following form -$$ -f_{drag} = -\frac{1}{2} C \rho A v^2 -$$

-

where C is the drag coefficient(0.5 for a sphere), $\rho$ is the air density (1.29kg/$m^3$) -and A is the cross-sectional area. -Generate points that have a bias of the value obtanied with -$f_{drag}$ using np.random.random.

-

Afterwards, use a second order polynomial to fit the data -generated and find the error associated to the approximation. -</font>

- -
-
-
-
- -
- -
-
- -
-
-
import scipy.optimize as optimize
-
- -
-
-
- -
-
- -
- -
-
-

Fit to a non-linear function

$$ -f(x)=A \operatorname{e}^{cx} + d\,. -$$

Determinar: $A,c,d$

- -
-
-
-
- -
- -
-
- -
-
-
T_values = np.array([222, 284, 308.5, 333, 358, 411, 477, 518, 880, 1080, 1259])
-C_values = np.array([0.1282, 0.2308, 0.2650, 0.3120 , 0.3547, 0.4530, 0.5556, 0.6154, 0.8932, 0.9103, 0.9316])
-
-x_samp = T_values
-y_samp = C_values
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
def func(x, A, c, d):
-    return A*np.exp(c*x) + d
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
# REGRESSION ------------------------------------------------------------------
-p0 = [-1, -3e-3, 1]                                        # guessed params
-w, _ = optimize.curve_fit(func, x_samp, y_samp, p0=p0)     
-print("E]stimated Parameters", w)  
-
-# Model
-x_lin=np.linspace(200,1350)
-y_model = func(x_lin, *w)
-
- -
-
-
- -
-
- -
-
- -
-
E]stimated Parameters [-1.66301087 -0.0026884   1.00995394]
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
x_lin = np.linspace(0, x_samp.max(), 50)                   # 50 evenly spaced digits between 0 and max
-# PLOT ------------------------------------------------------------------------
-# Visualize data and fitted curves
-plt.plot(x_samp, y_samp, "ko", label="Data")
-plt.plot(x_lin, y_model, "k--", label="Fit")
-plt.title("Least squares regression")
-plt.legend(loc="upper left")
-plt.xlabel('x')
-plt.ylabel('f(x)')
-
- -
-
-
- -
-
- -
-
- - - -
-
Text(0, 0.5, 'f(x)')
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
import time
-for i in range(100):
-    time.sleep(0.1)
-    if i%10==0:
-        print(i,end='\r')
-
- -
-
-
- -
-
- -
-
- -
-
90
-
-
-
-
-
-
- -
-
- -
- -
-
-

Example: exponential fit

-
-
-
-
- - - -
- -
-
-$$ -f(x)=a\exp\left[ -\frac{(x-\mu)^2}{2\sigma^2} \right] -$$

where $a$ is the height of the gaussian, $\mu$ is the mean (expected value), and $\sigma$ es la varianze

- -
-
-
-
- -
- -
-
- -
-
-
import pandas as pd
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
df=pd.read_csv('https://docs.google.com/spreadsheets/d/e/2PACX-1vTu_XE2dAiTcjHTfbaVKt7xEl_GnNeF_VYFsIBi5uM-gqBlBRfNHso-X1z3lxV7IW2f9UYKmZkSOYv-/pub?output=csv')
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
df['Guess']=df.Guess.str.replace(',','').astype(int)
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
bins=range(0,1500,100)
-
- -
-
-
- -
-
- -
- -
-
-

See solution: gaussian_fit.ipynb

- -
-
-
-
- -
- - -
- -
- -
-
-

Random Numbers

-
-
-
-
- -
- -
-
-

In nature it is not uncommon finding phenomena that are random intrinsic, this is why it becomes a necessity to produce random numbers in order to model such events. But, let us think about the operations that a computer can do, they are done following certain stablished rules, how then can be generated random numbers?

-

This is achieved until certain point, it is only possible produce pseudo numbers, i.e, numbers obtained following some basic rules. At sequence of numbers apparently random but that are going to repeat after some period.

-

Now, the most basic way to understand the generation of a pseudo-random number consists in following the next recurrence rule that produces integer random numbers

-$$ -r_{i+1} = (ar_i+b)\%N -$$

$r_i$ is the seed, $a$ and $b$ and $N$ are coefficients chose. Notice that $\%$ represents the module, then the numbers obtained are going to be smaller than N.

-

Now, consider the case when $ a= 3 $, $b = 2$ and $N = 10$ and the initial seed $r_0 = 3$. The new seed is the number obtaine -in the last step.

- -
-
-
-
- -
- -
-
- -
-
-
%pylab inline
-
- -
-
-
- -
-
- -
-
- -
-
Populating the interactive namespace from numpy and matplotlib
-
-
-
-
-
-
- -
-
/usr/local/lib/python3.5/dist-packages/IPython/core/magics/pylab.py:160: UserWarning: pylab import has clobbered these variables: ['colors', 'random']
-`%matplotlib` prevents importing * from pylab and numpy
-  "\n`%matplotlib` prevents importing * from pylab and numpy"
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
import numpy as np
-# Randon number function 
-def random_number(seed):
-    return (a*seed + b)%N
-
-#Constant values 
-a = 4
-b = 1
-N = 9
-#Amount of random numbers  
-N_iter = 15
-rnumber = np.zeros(N_iter+1)
-#Initial seed
-rnumber[0] = 4
-#rnumber[0] = 10
-
-for i in range(N_iter): 
-    rnumber[i+1] = random_number( rnumber[i])
-
-print ("Random numbers produced using a = %d, b = %d and N = %d\n" % ( a,b,N ))  
-print (rnumber[1:])   
-
- -
-
-
- -
-
- -
-
- -
-
Random numbers produced using a = 4, b = 1 and N = 9
-
-[8. 6. 7. 2. 0. 1. 5. 3. 4. 8. 6. 7. 2. 0. 1.]
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
import random
-import numpy as np
-import time
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
print( time.time() )
-time.sleep(2)
-print( time.time() )
-
- -
-
-
- -
-
- -
-
- -
-
1605636036.2581604
-1605636038.2598178
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
random.random() #seed is unix time
-
- -
-
-
- -
-
- -
-
- - - -
-
0.6982585360672241
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
x=random.seed(4890098)
-(random.random(),
-random.random(),
-random.random())
-
- -
-
-
- -
-
- -
-
- - - -
-
(0.6771981606438447, 0.7282646242796362, 0.12733022922307846)
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
np.random.random(5)
-
- -
-
-
- -
-
- -
-
- - - -
-
array([0.74979577, 0.77025198, 0.1943525 , 0.418922  , 0.91964572])
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
np.random.seed(2)
-np.random.random(5)
-
- -
-
-
- -
-
- -
-
- - - -
-
array([0.4359949 , 0.02592623, 0.54966248, 0.43532239, 0.4203678 ])
-
- -
-
-
-
- -
-
- -
- -
-
-

Notice that after N random numbers produced the apparently random sequence starts repeating again, i.e., N is the period of the sequence. Then, it is necessary to take N as big as possible but without incuring in an overflow. What happens when the initial seed is changed?

-

-

To generate random numbers can be used numpy library, specifically the set functions random. There is also another library -used random, but it contains few functions comparing with numpy. -To generate a random number between 0 and 1 initiallizing the seed with the actual time.

- -
-
-
-
- -
- -
-
- -
-
-
np.random.seed()
-np.random.random()
-
- -
-
-
- -
-
- -
-
- - - -
-
0.5246933156265494
-
- -
-
-
-
- -
-
- -
- -
-
-

To generate a number between and a number A

- -
-
-
-
- -
- -
-
- -
-
-
A = 100.
-A*np.random.random((5,5))
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[13.25980014, 10.85324426, 81.24657358, 73.5488896 , 76.84488754],
-       [34.51142695, 72.82941893, 61.76035147, 98.75100252, 77.34796303],
-       [28.27847299, 14.76777458, 55.78354501, 24.62013376, 36.56582928],
-       [81.08850504, 60.25923238, 71.22826739, 62.52388123, 56.28302001],
-       [89.37094444, 36.14415972, 16.15729293, 31.74634766, 24.41171835]])
-
- -
-
-
-
- -
-
- -
- -
-
-

To generate a random number between a range -B to B

- -
-
-
-
- -
- -
-
- -
-
-
B = 15
-B - 2*B*np.random.random()
-
- -
-
-
- -
-
- -
-
- - - -
-
-3.578128990519911
-
- -
-
-
-
- -
-
- -
- -
-
-

The implementation in numpy is with:

- -
-
-
-
- -
- -
-
- -
-
-
np.random.uniform(-15,15,(2,2))
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[  5.34784268,  -2.27612914],
-       [  7.8623893 , -13.88564232]])
-
- -
-
-
-
- -
-
- -
- -
-
-

Example 2

-
-
-
-
- -
- -
-
-

Random walk

Start at the origin and take a 2D random walk. It is chosen values for $\Delta x'$ and $\Delta y'$ in the range [-1,1]. -They are normalized so each step is of unit length.

- -
-
-
-
- -
- -
-
- -
-
-
#Initial positions
-x0 = 0.
-y0 = 0.
-pos = [x0,y0]
-#Number of random steps
-N_steps = 1000
-#Number of random walks
-N_walks = 3
-
-
-def Random_walk( pos, N ):
-    
-    #Initializing the seed
-    np.random.seed()
-    
-    x = np.zeros( N )    
-    y = np.zeros( N )    
-
-    #Initial conditions
-    x[0] = pos[0]
-    y[0] = pos[1]
-    
-    #Generating random positions
-    for i in range(1,N_steps):
-        x[i] = ( np.random.random(  ) - 0.5 )*2 + x[i-1]
-        y[i] = ( np.random.random(  ) - 0.5 )*2 + y[i-1]
-    
-    return x, y
-    
-
-colors = ('b', 'g', 'c', 'r', 'm', 'y', 'k')
-axisNum = 0
-plt.figure( figsize = (8,6) )
-
-#Plotting random walks
-for j,c in zip( range(N_walks),colors):
-    
-    axisNum += 1
-    x,y= Random_walk( pos, N_steps )
-    #If N_walks > repeat the colors
-    color = colors[axisNum % len(colors)]  
-    plt.plot(x,y,"v-", color = color, lw= 0.5, label = "walk %d"%(j+1))
-    
-
-plt.title("Random walks")
-plt.legend()
-
- -
-
-
- -
-
- -
-
- - - -
-
<matplotlib.legend.Legend at 0x7f95f6040e10>
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Activity

- -
-
-
-
- -
- -
-
-

-Radioactive decay: Spontaneous decay is a natural process in which a particle, with no external stimulation, decays into other -particles. Then, the total amount of particles in a sample decreases with time, so will the number of decays. -The probability decay is constant per particle and is given by

-$$ -P = -\lambda -$$

Determin when radioactive decay looks like exponential decay and when it looks stochastic depending on the initial number of particles $N(t)$ .For this, suposse that the decay rate is 0.3$\times 10^6 s^{-1}$ . Make a logarithmic plot to show the results. -</font>

- -
-
-
-
- -
- -
-
- -
-
-
np.random.uniform(-15,15,(2,2))
-
- -
-
-
- -
-
- -
-
- - - -
-
array([[ 1.56800444,  5.62105311],
-       [10.43483622, 14.89746624]])
-
- -
-
-
-
- -
-
- -
- -
-
-

Espacio de parámetros aleatorios

- -
-
-
-
- -
- -
-
- -
-
-
N=10000
-plt.plot(np.random.random(N),np.random.random(N),'r.')
-
- -
-
-
- -
-
- -
-
- - - -
-
[<matplotlib.lines.Line2D at 0x7f95f5c66a90>]
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Hasta dos ordenes de magnitud

- -
-
-
-
- -
- -
-
- -
-
-
N=10000
-plt.plot(np.random.uniform(1,100,N),np.random.uniform(1,100,N),'r.')
-
- -
-
-
- -
-
- -
-
- - - -
-
[<matplotlib.lines.Line2D at 0x7f95f5c42f98>]
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

Varios ordenes de magnitud: $10^{-4}$ a $10^2$

- -
-
-
-
- -
- -
-
- -
-
-
N=10000
-plt.loglog(np.random.uniform(1E-4,1E2,N),np.random.uniform(1E-4,1E2,N),'r.')
-
- -
-
-
- -
-
- -
-
- - - -
-
[<matplotlib.lines.Line2D at 0x7f95f5c00940>]
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
-

$x=10^{\log_{10}(x)}$

- -
-
-
-
- -
- -
-
- -
-
-
10**np.log10(24.456)
-
- -
-
-
- -
-
- -
-
- - - -
-
24.455999999999996
-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
N=10000
-xmin=3E-4;xmax=5E2
-ymin=xmin;ymax=xmax
-plt.loglog(  10**np.random.uniform(np.log10(xmin),np.log10(xmax),N),
-             10**np.random.uniform(np.log10(ymin),np.log10(ymax),N),'r.')
-
- -
-
-
- -
-
- -
-
- - - -
-
[<matplotlib.lines.Line2D at 0x7f95f6008dd8>]
-
- -
-
-
-
- - - -
- -
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
np.random.randint(1,100)
-
- -
-
-
- -
-
- -
-
- - - -
-
38
-
- -
-
-
-
- -
-
- - - - -
- \ No newline at end of file diff --git a/_build/images/C-3PO_droid.png b/_build/images/C-3PO_droid.png deleted file mode 100755 index 076176c..0000000 Binary files a/_build/images/C-3PO_droid.png and /dev/null differ diff --git a/_build/images/features/LagrangePoly_14_1.png b/_build/images/features/LagrangePoly_14_1.png deleted file mode 100644 index d263d01..0000000 Binary files a/_build/images/features/LagrangePoly_14_1.png and /dev/null differ diff --git a/_build/images/features/LagrangePoly_26_1.png b/_build/images/features/LagrangePoly_26_1.png deleted file mode 100644 index d263d01..0000000 Binary files a/_build/images/features/LagrangePoly_26_1.png and /dev/null differ diff --git a/_build/images/features/Minimization_17_0.png b/_build/images/features/Minimization_17_0.png deleted file mode 100644 index 7c774d5..0000000 Binary files a/_build/images/features/Minimization_17_0.png and /dev/null differ diff --git a/_build/images/features/Minimization_20_1.png b/_build/images/features/Minimization_20_1.png deleted file mode 100644 index 9d1d9dc..0000000 Binary files a/_build/images/features/Minimization_20_1.png and /dev/null differ diff --git a/_build/images/features/Minimization_27_1.png b/_build/images/features/Minimization_27_1.png deleted file mode 100644 index 594a1b8..0000000 Binary files a/_build/images/features/Minimization_27_1.png and /dev/null differ diff --git a/_build/images/features/Minimization_45_0.png b/_build/images/features/Minimization_45_0.png deleted file mode 100644 index 62ecffb..0000000 Binary files a/_build/images/features/Minimization_45_0.png and /dev/null differ diff --git a/_build/images/features/Minimization_48_0.png b/_build/images/features/Minimization_48_0.png deleted file mode 100644 index 8d2acf8..0000000 Binary files a/_build/images/features/Minimization_48_0.png and /dev/null differ diff --git a/_build/images/features/Minimization_67_0.png b/_build/images/features/Minimization_67_0.png deleted file mode 100644 index 7f11d92..0000000 Binary files a/_build/images/features/Minimization_67_0.png and /dev/null differ diff --git a/_build/images/features/algorithms-convergence_10_0.png b/_build/images/features/algorithms-convergence_10_0.png deleted file mode 100644 index 20b8c2b..0000000 Binary files a/_build/images/features/algorithms-convergence_10_0.png and /dev/null differ diff --git a/_build/images/features/algorithms-convergence_11_0.png b/_build/images/features/algorithms-convergence_11_0.png deleted file mode 100644 index 20b8c2b..0000000 Binary files a/_build/images/features/algorithms-convergence_11_0.png and /dev/null differ diff --git a/_build/images/features/algorithms-convergence_14_0.png b/_build/images/features/algorithms-convergence_14_0.png deleted file mode 100644 index f3a7213..0000000 Binary files a/_build/images/features/algorithms-convergence_14_0.png and /dev/null differ diff --git a/_build/images/features/algorithms-convergence_15_0.png b/_build/images/features/algorithms-convergence_15_0.png deleted file mode 100644 index f3a7213..0000000 Binary files a/_build/images/features/algorithms-convergence_15_0.png and /dev/null differ diff --git a/_build/images/features/algorithms-convergence_23_0.png b/_build/images/features/algorithms-convergence_23_0.png deleted file mode 100644 index 6e33ad2..0000000 Binary files a/_build/images/features/algorithms-convergence_23_0.png and /dev/null differ diff --git a/_build/images/features/algorithms-convergence_24_0.png b/_build/images/features/algorithms-convergence_24_0.png deleted file mode 100644 index 6e33ad2..0000000 Binary files a/_build/images/features/algorithms-convergence_24_0.png and /dev/null differ diff --git a/_build/images/features/algorithms-convergence_8_0.png b/_build/images/features/algorithms-convergence_8_0.png deleted file mode 100644 index 0567121..0000000 Binary files a/_build/images/features/algorithms-convergence_8_0.png and /dev/null differ diff --git a/_build/images/features/algorithms-convergence_9_0.png b/_build/images/features/algorithms-convergence_9_0.png deleted file mode 100644 index 0567121..0000000 Binary files a/_build/images/features/algorithms-convergence_9_0.png and /dev/null differ diff --git a/_build/images/features/differential-equations_100_1.png b/_build/images/features/differential-equations_100_1.png deleted file mode 100644 index ddd37cb..0000000 Binary files a/_build/images/features/differential-equations_100_1.png and /dev/null differ diff --git a/_build/images/features/differential-equations_101_1.png b/_build/images/features/differential-equations_101_1.png deleted file mode 100644 index 9992265..0000000 Binary files a/_build/images/features/differential-equations_101_1.png and /dev/null differ diff --git a/_build/images/features/differential-equations_102_1.png b/_build/images/features/differential-equations_102_1.png deleted file mode 100644 index c4080d8..0000000 Binary files a/_build/images/features/differential-equations_102_1.png and /dev/null differ diff --git a/_build/images/features/differential-equations_103_1.png b/_build/images/features/differential-equations_103_1.png deleted file mode 100644 index c4080d8..0000000 Binary files a/_build/images/features/differential-equations_103_1.png and /dev/null differ diff --git a/_build/images/features/differential-equations_113_0.png b/_build/images/features/differential-equations_113_0.png deleted file mode 100644 index bb83d42..0000000 Binary files a/_build/images/features/differential-equations_113_0.png and /dev/null differ diff --git a/_build/images/features/differential-equations_123_0.png b/_build/images/features/differential-equations_123_0.png deleted file mode 100644 index bb83d42..0000000 Binary files a/_build/images/features/differential-equations_123_0.png and /dev/null differ diff --git a/_build/images/features/differential-equations_124_0.png b/_build/images/features/differential-equations_124_0.png deleted file mode 100644 index bb83d42..0000000 Binary files a/_build/images/features/differential-equations_124_0.png and /dev/null differ diff --git a/_build/images/features/differential-equations_21_1.png b/_build/images/features/differential-equations_21_1.png deleted file mode 100644 index 3eede77..0000000 Binary files a/_build/images/features/differential-equations_21_1.png and /dev/null differ diff --git a/_build/images/features/differential-equations_23_0.png b/_build/images/features/differential-equations_23_0.png deleted file mode 100644 index 63ae276..0000000 Binary files a/_build/images/features/differential-equations_23_0.png and /dev/null differ diff --git a/_build/images/features/differential-equations_31_1.png b/_build/images/features/differential-equations_31_1.png deleted file mode 100644 index 3a2f9c0..0000000 Binary files a/_build/images/features/differential-equations_31_1.png and /dev/null differ diff --git a/_build/images/features/differential-equations_32_1.png b/_build/images/features/differential-equations_32_1.png deleted file mode 100644 index 2a36dd5..0000000 Binary files a/_build/images/features/differential-equations_32_1.png and /dev/null differ diff --git a/_build/images/features/differential-equations_33_1.png b/_build/images/features/differential-equations_33_1.png deleted file mode 100644 index 23e72e4..0000000 Binary files a/_build/images/features/differential-equations_33_1.png and /dev/null differ diff --git a/_build/images/features/differential-equations_34_0.png b/_build/images/features/differential-equations_34_0.png deleted file mode 100644 index 780b53f..0000000 Binary files a/_build/images/features/differential-equations_34_0.png and /dev/null differ diff --git a/_build/images/features/differential-equations_48_0.png b/_build/images/features/differential-equations_48_0.png deleted file mode 100644 index 48fb306..0000000 Binary files a/_build/images/features/differential-equations_48_0.png and /dev/null differ diff --git a/_build/images/features/differential-equations_50_0.png b/_build/images/features/differential-equations_50_0.png deleted file mode 100644 index 12b0e0e..0000000 Binary files a/_build/images/features/differential-equations_50_0.png and /dev/null differ diff --git a/_build/images/features/differential-equations_52_0.png b/_build/images/features/differential-equations_52_0.png deleted file mode 100644 index 39afcea..0000000 Binary files a/_build/images/features/differential-equations_52_0.png and /dev/null differ diff --git a/_build/images/features/differential-equations_61_0.png b/_build/images/features/differential-equations_61_0.png deleted file mode 100644 index 7469434..0000000 Binary files a/_build/images/features/differential-equations_61_0.png and /dev/null differ diff --git a/_build/images/features/differential-equations_62_0.png b/_build/images/features/differential-equations_62_0.png deleted file mode 100644 index 87ce804..0000000 Binary files a/_build/images/features/differential-equations_62_0.png and /dev/null differ diff --git a/_build/images/features/differential-equations_65_0.png b/_build/images/features/differential-equations_65_0.png deleted file mode 100644 index 7469434..0000000 Binary files a/_build/images/features/differential-equations_65_0.png and /dev/null differ diff --git a/_build/images/features/differential-equations_71_0.png b/_build/images/features/differential-equations_71_0.png deleted file mode 100644 index 7a3cef1..0000000 Binary files a/_build/images/features/differential-equations_71_0.png and /dev/null differ diff --git a/_build/images/features/differential-equations_71_1.png b/_build/images/features/differential-equations_71_1.png deleted file mode 100644 index 02e5d30..0000000 Binary files a/_build/images/features/differential-equations_71_1.png and /dev/null differ diff --git a/_build/images/features/differential-equations_72_0.png b/_build/images/features/differential-equations_72_0.png deleted file mode 100644 index 395d09c..0000000 Binary files a/_build/images/features/differential-equations_72_0.png and /dev/null differ diff --git a/_build/images/features/differential-equations_73_1.png b/_build/images/features/differential-equations_73_1.png deleted file mode 100644 index c2feb99..0000000 Binary files a/_build/images/features/differential-equations_73_1.png and /dev/null differ diff --git a/_build/images/features/differential-equations_75_0.png b/_build/images/features/differential-equations_75_0.png deleted file mode 100644 index 7a3cef1..0000000 Binary files a/_build/images/features/differential-equations_75_0.png and /dev/null differ diff --git a/_build/images/features/differential-equations_81_1.png b/_build/images/features/differential-equations_81_1.png deleted file mode 100644 index 02e5d30..0000000 Binary files a/_build/images/features/differential-equations_81_1.png and /dev/null differ diff --git a/_build/images/features/differential-equations_82_1.png b/_build/images/features/differential-equations_82_1.png deleted file mode 100644 index 77ae00e..0000000 Binary files a/_build/images/features/differential-equations_82_1.png and /dev/null differ diff --git a/_build/images/features/differential-equations_83_1.png b/_build/images/features/differential-equations_83_1.png deleted file mode 100644 index c2feb99..0000000 Binary files a/_build/images/features/differential-equations_83_1.png and /dev/null differ diff --git a/_build/images/features/differential-equations_84_0.png b/_build/images/features/differential-equations_84_0.png deleted file mode 100644 index 7960cc1..0000000 Binary files a/_build/images/features/differential-equations_84_0.png and /dev/null differ diff --git a/_build/images/features/differential-equations_84_1.png b/_build/images/features/differential-equations_84_1.png deleted file mode 100644 index c2feb99..0000000 Binary files a/_build/images/features/differential-equations_84_1.png and /dev/null differ diff --git a/_build/images/features/differential-equations_87_1.png b/_build/images/features/differential-equations_87_1.png deleted file mode 100644 index caa7383..0000000 Binary files a/_build/images/features/differential-equations_87_1.png and /dev/null differ diff --git a/_build/images/features/differential-equations_89_1.png b/_build/images/features/differential-equations_89_1.png deleted file mode 100644 index ddd37cb..0000000 Binary files a/_build/images/features/differential-equations_89_1.png and /dev/null differ diff --git a/_build/images/features/differential-equations_90_1.png b/_build/images/features/differential-equations_90_1.png deleted file mode 100644 index d77f6f8..0000000 Binary files a/_build/images/features/differential-equations_90_1.png and /dev/null differ diff --git a/_build/images/features/differential-equations_91_1.png b/_build/images/features/differential-equations_91_1.png deleted file mode 100644 index d77f6f8..0000000 Binary files a/_build/images/features/differential-equations_91_1.png and /dev/null differ diff --git a/_build/images/features/differential-equations_92_1.png b/_build/images/features/differential-equations_92_1.png deleted file mode 100644 index 468727f..0000000 Binary files a/_build/images/features/differential-equations_92_1.png and /dev/null differ diff --git a/_build/images/features/differential-equations_93_1.png b/_build/images/features/differential-equations_93_1.png deleted file mode 100644 index 468727f..0000000 Binary files a/_build/images/features/differential-equations_93_1.png and /dev/null differ diff --git a/_build/images/features/differential-equations_94_0.png b/_build/images/features/differential-equations_94_0.png deleted file mode 100644 index 7960cc1..0000000 Binary files a/_build/images/features/differential-equations_94_0.png and /dev/null differ diff --git a/_build/images/features/differential-equations_94_1.png b/_build/images/features/differential-equations_94_1.png deleted file mode 100644 index 1e8ed49..0000000 Binary files a/_build/images/features/differential-equations_94_1.png and /dev/null differ diff --git a/_build/images/features/differential-equations_95_0.png b/_build/images/features/differential-equations_95_0.png deleted file mode 100644 index 7960cc1..0000000 Binary files a/_build/images/features/differential-equations_95_0.png and /dev/null differ diff --git a/_build/images/features/differential-equations_96_0.png b/_build/images/features/differential-equations_96_0.png deleted file mode 100644 index ce871b5..0000000 Binary files a/_build/images/features/differential-equations_96_0.png and /dev/null differ diff --git a/_build/images/features/differential-equations_97_1.png b/_build/images/features/differential-equations_97_1.png deleted file mode 100644 index caa7383..0000000 Binary files a/_build/images/features/differential-equations_97_1.png and /dev/null differ diff --git a/_build/images/features/differential-equations_98_1.png b/_build/images/features/differential-equations_98_1.png deleted file mode 100644 index caa7383..0000000 Binary files a/_build/images/features/differential-equations_98_1.png and /dev/null differ diff --git a/_build/images/features/differential-equations_99_1.png b/_build/images/features/differential-equations_99_1.png deleted file mode 100644 index 188ccc8..0000000 Binary files a/_build/images/features/differential-equations_99_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_100_1.png b/_build/images/features/interpolation_100_1.png deleted file mode 100644 index 156e64e..0000000 Binary files a/_build/images/features/interpolation_100_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_102_1.png b/_build/images/features/interpolation_102_1.png deleted file mode 100644 index 37169af..0000000 Binary files a/_build/images/features/interpolation_102_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_104_2.png b/_build/images/features/interpolation_104_2.png deleted file mode 100644 index a5b7528..0000000 Binary files a/_build/images/features/interpolation_104_2.png and /dev/null differ diff --git a/_build/images/features/interpolation_106_1.png b/_build/images/features/interpolation_106_1.png deleted file mode 100644 index 4a514cd..0000000 Binary files a/_build/images/features/interpolation_106_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_107_1.png b/_build/images/features/interpolation_107_1.png deleted file mode 100644 index 4a514cd..0000000 Binary files a/_build/images/features/interpolation_107_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_113_1.png b/_build/images/features/interpolation_113_1.png deleted file mode 100644 index 433b96c..0000000 Binary files a/_build/images/features/interpolation_113_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_119_0.png b/_build/images/features/interpolation_119_0.png deleted file mode 100644 index 0e84095..0000000 Binary files a/_build/images/features/interpolation_119_0.png and /dev/null differ diff --git a/_build/images/features/interpolation_119_1.png b/_build/images/features/interpolation_119_1.png deleted file mode 100644 index 4a514cd..0000000 Binary files a/_build/images/features/interpolation_119_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_121_1.png b/_build/images/features/interpolation_121_1.png deleted file mode 100644 index bcb1182..0000000 Binary files a/_build/images/features/interpolation_121_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_123_1.png b/_build/images/features/interpolation_123_1.png deleted file mode 100644 index e2ffc20..0000000 Binary files a/_build/images/features/interpolation_123_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_125_2.png b/_build/images/features/interpolation_125_2.png deleted file mode 100644 index 5928cb2..0000000 Binary files a/_build/images/features/interpolation_125_2.png and /dev/null differ diff --git a/_build/images/features/interpolation_126_1.png b/_build/images/features/interpolation_126_1.png deleted file mode 100644 index 586d164..0000000 Binary files a/_build/images/features/interpolation_126_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_127_1.png b/_build/images/features/interpolation_127_1.png deleted file mode 100644 index 06f7e84..0000000 Binary files a/_build/images/features/interpolation_127_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_129_1.png b/_build/images/features/interpolation_129_1.png deleted file mode 100644 index 1599ac3..0000000 Binary files a/_build/images/features/interpolation_129_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_130_1.png b/_build/images/features/interpolation_130_1.png deleted file mode 100644 index 4936a15..0000000 Binary files a/_build/images/features/interpolation_130_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_131_1.png b/_build/images/features/interpolation_131_1.png deleted file mode 100644 index 4936a15..0000000 Binary files a/_build/images/features/interpolation_131_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_132_1.png b/_build/images/features/interpolation_132_1.png deleted file mode 100644 index c1fa950..0000000 Binary files a/_build/images/features/interpolation_132_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_133_1.png b/_build/images/features/interpolation_133_1.png deleted file mode 100644 index b9f4e53..0000000 Binary files a/_build/images/features/interpolation_133_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_134_1.png b/_build/images/features/interpolation_134_1.png deleted file mode 100644 index b9f4e53..0000000 Binary files a/_build/images/features/interpolation_134_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_139_1.png b/_build/images/features/interpolation_139_1.png deleted file mode 100644 index 586d164..0000000 Binary files a/_build/images/features/interpolation_139_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_141_1.png b/_build/images/features/interpolation_141_1.png deleted file mode 100644 index 586d164..0000000 Binary files a/_build/images/features/interpolation_141_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_142_1.png b/_build/images/features/interpolation_142_1.png deleted file mode 100644 index 06f7e84..0000000 Binary files a/_build/images/features/interpolation_142_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_143_1.png b/_build/images/features/interpolation_143_1.png deleted file mode 100644 index 4936a15..0000000 Binary files a/_build/images/features/interpolation_143_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_144_1.png b/_build/images/features/interpolation_144_1.png deleted file mode 100644 index 1599ac3..0000000 Binary files a/_build/images/features/interpolation_144_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_145_1.png b/_build/images/features/interpolation_145_1.png deleted file mode 100644 index 4936a15..0000000 Binary files a/_build/images/features/interpolation_145_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_146_1.png b/_build/images/features/interpolation_146_1.png deleted file mode 100644 index b9f4e53..0000000 Binary files a/_build/images/features/interpolation_146_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_147_1.png b/_build/images/features/interpolation_147_1.png deleted file mode 100644 index c1fa950..0000000 Binary files a/_build/images/features/interpolation_147_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_148_1.png b/_build/images/features/interpolation_148_1.png deleted file mode 100644 index b9f4e53..0000000 Binary files a/_build/images/features/interpolation_148_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_159_0.png b/_build/images/features/interpolation_159_0.png deleted file mode 100644 index 6776f10..0000000 Binary files a/_build/images/features/interpolation_159_0.png and /dev/null differ diff --git a/_build/images/features/interpolation_170_1.png b/_build/images/features/interpolation_170_1.png deleted file mode 100644 index 586d164..0000000 Binary files a/_build/images/features/interpolation_170_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_173_1.png b/_build/images/features/interpolation_173_1.png deleted file mode 100644 index 1599ac3..0000000 Binary files a/_build/images/features/interpolation_173_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_174_1.png b/_build/images/features/interpolation_174_1.png deleted file mode 100644 index 4936a15..0000000 Binary files a/_build/images/features/interpolation_174_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_176_0.png b/_build/images/features/interpolation_176_0.png deleted file mode 100644 index a559864..0000000 Binary files a/_build/images/features/interpolation_176_0.png and /dev/null differ diff --git a/_build/images/features/interpolation_176_1.png b/_build/images/features/interpolation_176_1.png deleted file mode 100644 index c1fa950..0000000 Binary files a/_build/images/features/interpolation_176_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_177_0.png b/_build/images/features/interpolation_177_0.png deleted file mode 100644 index 690a7e1..0000000 Binary files a/_build/images/features/interpolation_177_0.png and /dev/null differ diff --git a/_build/images/features/interpolation_177_1.png b/_build/images/features/interpolation_177_1.png deleted file mode 100644 index b9f4e53..0000000 Binary files a/_build/images/features/interpolation_177_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_199_1.png b/_build/images/features/interpolation_199_1.png deleted file mode 100644 index 586d164..0000000 Binary files a/_build/images/features/interpolation_199_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_202_1.png b/_build/images/features/interpolation_202_1.png deleted file mode 100644 index 1599ac3..0000000 Binary files a/_build/images/features/interpolation_202_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_203_1.png b/_build/images/features/interpolation_203_1.png deleted file mode 100644 index 4936a15..0000000 Binary files a/_build/images/features/interpolation_203_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_205_1.png b/_build/images/features/interpolation_205_1.png deleted file mode 100644 index c1fa950..0000000 Binary files a/_build/images/features/interpolation_205_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_206_1.png b/_build/images/features/interpolation_206_1.png deleted file mode 100644 index b9f4e53..0000000 Binary files a/_build/images/features/interpolation_206_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_44_0.png b/_build/images/features/interpolation_44_0.png deleted file mode 100644 index 5628e66..0000000 Binary files a/_build/images/features/interpolation_44_0.png and /dev/null differ diff --git a/_build/images/features/interpolation_45_0.png b/_build/images/features/interpolation_45_0.png deleted file mode 100644 index 5628e66..0000000 Binary files a/_build/images/features/interpolation_45_0.png and /dev/null differ diff --git a/_build/images/features/interpolation_47_1.png b/_build/images/features/interpolation_47_1.png deleted file mode 100644 index 5a16da8..0000000 Binary files a/_build/images/features/interpolation_47_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_48_0.png b/_build/images/features/interpolation_48_0.png deleted file mode 100644 index bd10b2f..0000000 Binary files a/_build/images/features/interpolation_48_0.png and /dev/null differ diff --git a/_build/images/features/interpolation_48_1.png b/_build/images/features/interpolation_48_1.png deleted file mode 100644 index 5a16da8..0000000 Binary files a/_build/images/features/interpolation_48_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_58_0.png b/_build/images/features/interpolation_58_0.png deleted file mode 100644 index 5628e66..0000000 Binary files a/_build/images/features/interpolation_58_0.png and /dev/null differ diff --git a/_build/images/features/interpolation_58_6.png b/_build/images/features/interpolation_58_6.png deleted file mode 100644 index 9b0fbef..0000000 Binary files a/_build/images/features/interpolation_58_6.png and /dev/null differ diff --git a/_build/images/features/interpolation_60_0.png b/_build/images/features/interpolation_60_0.png deleted file mode 100644 index 4bf104b..0000000 Binary files a/_build/images/features/interpolation_60_0.png and /dev/null differ diff --git a/_build/images/features/interpolation_61_0.png b/_build/images/features/interpolation_61_0.png deleted file mode 100644 index bbd25e4..0000000 Binary files a/_build/images/features/interpolation_61_0.png and /dev/null differ diff --git a/_build/images/features/interpolation_69_1.png b/_build/images/features/interpolation_69_1.png deleted file mode 100644 index cf50a26..0000000 Binary files a/_build/images/features/interpolation_69_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_70_1.png b/_build/images/features/interpolation_70_1.png deleted file mode 100644 index cf50a26..0000000 Binary files a/_build/images/features/interpolation_70_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_73_0.png b/_build/images/features/interpolation_73_0.png deleted file mode 100644 index 52fde58..0000000 Binary files a/_build/images/features/interpolation_73_0.png and /dev/null differ diff --git a/_build/images/features/interpolation_75_0.png b/_build/images/features/interpolation_75_0.png deleted file mode 100644 index abcbdd2..0000000 Binary files a/_build/images/features/interpolation_75_0.png and /dev/null differ diff --git a/_build/images/features/interpolation_78_0.png b/_build/images/features/interpolation_78_0.png deleted file mode 100644 index e4371ff..0000000 Binary files a/_build/images/features/interpolation_78_0.png and /dev/null differ diff --git a/_build/images/features/interpolation_79_1.png b/_build/images/features/interpolation_79_1.png deleted file mode 100644 index ce5b0a0..0000000 Binary files a/_build/images/features/interpolation_79_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_80_1.png b/_build/images/features/interpolation_80_1.png deleted file mode 100644 index ce5b0a0..0000000 Binary files a/_build/images/features/interpolation_80_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_82_1.png b/_build/images/features/interpolation_82_1.png deleted file mode 100644 index 8d49851..0000000 Binary files a/_build/images/features/interpolation_82_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_85_0.png b/_build/images/features/interpolation_85_0.png deleted file mode 100644 index 6155cb9..0000000 Binary files a/_build/images/features/interpolation_85_0.png and /dev/null differ diff --git a/_build/images/features/interpolation_86_0.png b/_build/images/features/interpolation_86_0.png deleted file mode 100644 index 6155cb9..0000000 Binary files a/_build/images/features/interpolation_86_0.png and /dev/null differ diff --git a/_build/images/features/interpolation_87_1.png b/_build/images/features/interpolation_87_1.png deleted file mode 100644 index e99dc4b..0000000 Binary files a/_build/images/features/interpolation_87_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_88_1.png b/_build/images/features/interpolation_88_1.png deleted file mode 100644 index e99dc4b..0000000 Binary files a/_build/images/features/interpolation_88_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_89_1.png b/_build/images/features/interpolation_89_1.png deleted file mode 100644 index f8fada8..0000000 Binary files a/_build/images/features/interpolation_89_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_90_0.png b/_build/images/features/interpolation_90_0.png deleted file mode 100644 index 1fe8b48..0000000 Binary files a/_build/images/features/interpolation_90_0.png and /dev/null differ diff --git a/_build/images/features/interpolation_90_1.png b/_build/images/features/interpolation_90_1.png deleted file mode 100644 index f8fada8..0000000 Binary files a/_build/images/features/interpolation_90_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_91_2.png b/_build/images/features/interpolation_91_2.png deleted file mode 100644 index 97c741e..0000000 Binary files a/_build/images/features/interpolation_91_2.png and /dev/null differ diff --git a/_build/images/features/interpolation_92_1.png b/_build/images/features/interpolation_92_1.png deleted file mode 100644 index b9d0d39..0000000 Binary files a/_build/images/features/interpolation_92_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_92_2.png b/_build/images/features/interpolation_92_2.png deleted file mode 100644 index 97c741e..0000000 Binary files a/_build/images/features/interpolation_92_2.png and /dev/null differ diff --git a/_build/images/features/interpolation_93_1.png b/_build/images/features/interpolation_93_1.png deleted file mode 100644 index f05b9ae..0000000 Binary files a/_build/images/features/interpolation_93_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_94_0.png b/_build/images/features/interpolation_94_0.png deleted file mode 100644 index d00b6f3..0000000 Binary files a/_build/images/features/interpolation_94_0.png and /dev/null differ diff --git a/_build/images/features/interpolation_94_1.png b/_build/images/features/interpolation_94_1.png deleted file mode 100644 index f05b9ae..0000000 Binary files a/_build/images/features/interpolation_94_1.png and /dev/null differ diff --git a/_build/images/features/interpolation_98_0.png b/_build/images/features/interpolation_98_0.png deleted file mode 100644 index 0e84095..0000000 Binary files a/_build/images/features/interpolation_98_0.png and /dev/null differ diff --git a/_build/images/features/interpolation_details_23_1.png b/_build/images/features/interpolation_details_23_1.png deleted file mode 100644 index 982742c..0000000 Binary files a/_build/images/features/interpolation_details_23_1.png and /dev/null differ diff --git a/_build/images/features/ipython-notebooks_12_1.png b/_build/images/features/ipython-notebooks_12_1.png deleted file mode 100644 index 3c009a6..0000000 Binary files a/_build/images/features/ipython-notebooks_12_1.png and /dev/null differ diff --git a/_build/images/features/ipython-notebooks_19_0.png b/_build/images/features/ipython-notebooks_19_0.png deleted file mode 100644 index 0e42083..0000000 Binary files a/_build/images/features/ipython-notebooks_19_0.png and /dev/null differ diff --git a/_build/images/features/ipython-notebooks_22_0.png b/_build/images/features/ipython-notebooks_22_0.png deleted file mode 100644 index c1b0234..0000000 Binary files a/_build/images/features/ipython-notebooks_22_0.png and /dev/null differ diff --git a/_build/images/features/ipython-notebooks_29_0.png b/_build/images/features/ipython-notebooks_29_0.png deleted file mode 100644 index 0e42083..0000000 Binary files a/_build/images/features/ipython-notebooks_29_0.png and /dev/null differ diff --git a/_build/images/features/least_action_minimization_22_1.png b/_build/images/features/least_action_minimization_22_1.png deleted file mode 100644 index 818c8d9..0000000 Binary files a/_build/images/features/least_action_minimization_22_1.png and /dev/null differ diff --git a/_build/images/features/least_action_minimization_27_0.png b/_build/images/features/least_action_minimization_27_0.png deleted file mode 100644 index c5029e3..0000000 Binary files a/_build/images/features/least_action_minimization_27_0.png and /dev/null differ diff --git a/_build/images/features/least_action_minimization_40_0.png b/_build/images/features/least_action_minimization_40_0.png deleted file mode 100644 index 29c7af1..0000000 Binary files a/_build/images/features/least_action_minimization_40_0.png and /dev/null differ diff --git a/_build/images/features/least_action_minimization_40_1.png b/_build/images/features/least_action_minimization_40_1.png deleted file mode 100644 index 41a6215..0000000 Binary files a/_build/images/features/least_action_minimization_40_1.png and /dev/null differ diff --git a/_build/images/features/least_action_minimization_45_1.png b/_build/images/features/least_action_minimization_45_1.png deleted file mode 100644 index f789d2d..0000000 Binary files a/_build/images/features/least_action_minimization_45_1.png and /dev/null differ diff --git a/_build/images/features/least_action_minimization_46_0.png b/_build/images/features/least_action_minimization_46_0.png deleted file mode 100644 index 09a6f7e..0000000 Binary files a/_build/images/features/least_action_minimization_46_0.png and /dev/null differ diff --git a/_build/images/features/least_action_minimization_47_1.png b/_build/images/features/least_action_minimization_47_1.png deleted file mode 100644 index 8090463..0000000 Binary files a/_build/images/features/least_action_minimization_47_1.png and /dev/null differ diff --git a/_build/images/features/least_action_minimization_48_1.png b/_build/images/features/least_action_minimization_48_1.png deleted file mode 100644 index 8090463..0000000 Binary files a/_build/images/features/least_action_minimization_48_1.png and /dev/null differ diff --git a/_build/images/features/linear-algebra_101_0.png b/_build/images/features/linear-algebra_101_0.png deleted file mode 100644 index 48f2a81..0000000 Binary files a/_build/images/features/linear-algebra_101_0.png and /dev/null differ diff --git a/_build/images/features/linear-algebra_102_0.png b/_build/images/features/linear-algebra_102_0.png deleted file mode 100644 index d8090ff..0000000 Binary files a/_build/images/features/linear-algebra_102_0.png and /dev/null differ diff --git a/_build/images/features/linear-algebra_103_0.png b/_build/images/features/linear-algebra_103_0.png deleted file mode 100644 index d8090ff..0000000 Binary files a/_build/images/features/linear-algebra_103_0.png and /dev/null differ diff --git a/_build/images/features/linear-algebra_121_2.png b/_build/images/features/linear-algebra_121_2.png deleted file mode 100644 index 39d7b2d..0000000 Binary files a/_build/images/features/linear-algebra_121_2.png and /dev/null differ diff --git a/_build/images/features/linear-algebra_122_2.png b/_build/images/features/linear-algebra_122_2.png deleted file mode 100644 index 39d7b2d..0000000 Binary files a/_build/images/features/linear-algebra_122_2.png and /dev/null differ diff --git a/_build/images/features/linear-algebra_127_0.png b/_build/images/features/linear-algebra_127_0.png deleted file mode 100644 index 9746a09..0000000 Binary files a/_build/images/features/linear-algebra_127_0.png and /dev/null differ diff --git a/_build/images/features/linear-algebra_128_0.png b/_build/images/features/linear-algebra_128_0.png deleted file mode 100644 index 413040e..0000000 Binary files a/_build/images/features/linear-algebra_128_0.png and /dev/null differ diff --git a/_build/images/features/linear-algebra_138_0.png b/_build/images/features/linear-algebra_138_0.png deleted file mode 100644 index 9746a09..0000000 Binary files a/_build/images/features/linear-algebra_138_0.png and /dev/null differ diff --git a/_build/images/features/linear-algebra_139_0.png b/_build/images/features/linear-algebra_139_0.png deleted file mode 100644 index 413040e..0000000 Binary files a/_build/images/features/linear-algebra_139_0.png and /dev/null differ diff --git a/_build/images/features/linear-algebra_141_0.png b/_build/images/features/linear-algebra_141_0.png deleted file mode 100644 index 9746a09..0000000 Binary files a/_build/images/features/linear-algebra_141_0.png and /dev/null differ diff --git a/_build/images/features/linear-algebra_142_0.png b/_build/images/features/linear-algebra_142_0.png deleted file mode 100644 index 413040e..0000000 Binary files a/_build/images/features/linear-algebra_142_0.png and /dev/null differ diff --git a/_build/images/features/linear-algebra_147_2.png b/_build/images/features/linear-algebra_147_2.png deleted file mode 100644 index 39d7b2d..0000000 Binary files a/_build/images/features/linear-algebra_147_2.png and /dev/null differ diff --git a/_build/images/features/linear-algebra_158_0.png b/_build/images/features/linear-algebra_158_0.png deleted file mode 100644 index 3015f52..0000000 Binary files a/_build/images/features/linear-algebra_158_0.png and /dev/null differ diff --git a/_build/images/features/linear-algebra_158_2.png b/_build/images/features/linear-algebra_158_2.png deleted file mode 100644 index 39d7b2d..0000000 Binary files a/_build/images/features/linear-algebra_158_2.png and /dev/null differ diff --git a/_build/images/features/linear-algebra_159_0.png b/_build/images/features/linear-algebra_159_0.png deleted file mode 100644 index 3015f52..0000000 Binary files a/_build/images/features/linear-algebra_159_0.png and /dev/null differ diff --git a/_build/images/features/linear-algebra_161_2.png b/_build/images/features/linear-algebra_161_2.png deleted file mode 100644 index 39d7b2d..0000000 Binary files a/_build/images/features/linear-algebra_161_2.png and /dev/null differ diff --git a/_build/images/features/linear-algebra_184_0.png b/_build/images/features/linear-algebra_184_0.png deleted file mode 100644 index 3015f52..0000000 Binary files a/_build/images/features/linear-algebra_184_0.png and /dev/null differ diff --git a/_build/images/features/linear-algebra_195_0.png b/_build/images/features/linear-algebra_195_0.png deleted file mode 100644 index 3015f52..0000000 Binary files a/_build/images/features/linear-algebra_195_0.png and /dev/null differ diff --git a/_build/images/features/linear-algebra_24_0.png b/_build/images/features/linear-algebra_24_0.png deleted file mode 100644 index 0b089c9..0000000 Binary files a/_build/images/features/linear-algebra_24_0.png and /dev/null differ diff --git a/_build/images/features/linear-algebra_26_1.png b/_build/images/features/linear-algebra_26_1.png deleted file mode 100644 index a14130e..0000000 Binary files a/_build/images/features/linear-algebra_26_1.png and /dev/null differ diff --git a/_build/images/features/linear-algebra_28_0.png b/_build/images/features/linear-algebra_28_0.png deleted file mode 100644 index 131c0d6..0000000 Binary files a/_build/images/features/linear-algebra_28_0.png and /dev/null differ diff --git a/_build/images/features/linear-algebra_30_0.png b/_build/images/features/linear-algebra_30_0.png deleted file mode 100644 index bf7686e..0000000 Binary files a/_build/images/features/linear-algebra_30_0.png and /dev/null differ diff --git a/_build/images/features/linear-algebra_32_0.png b/_build/images/features/linear-algebra_32_0.png deleted file mode 100644 index 2dd9e1f..0000000 Binary files a/_build/images/features/linear-algebra_32_0.png and /dev/null differ diff --git a/_build/images/features/linear-algebra_32_1.png b/_build/images/features/linear-algebra_32_1.png deleted file mode 100644 index 06fb4b6..0000000 Binary files a/_build/images/features/linear-algebra_32_1.png and /dev/null differ diff --git a/_build/images/features/linear-algebra_34_0.png b/_build/images/features/linear-algebra_34_0.png deleted file mode 100644 index d5891e2..0000000 Binary files a/_build/images/features/linear-algebra_34_0.png and /dev/null differ diff --git a/_build/images/features/linear-algebra_42_0.png b/_build/images/features/linear-algebra_42_0.png deleted file mode 100644 index 88843cc..0000000 Binary files a/_build/images/features/linear-algebra_42_0.png and /dev/null differ diff --git a/_build/images/features/linear-algebra_44_0.png b/_build/images/features/linear-algebra_44_0.png deleted file mode 100644 index 34429bb..0000000 Binary files a/_build/images/features/linear-algebra_44_0.png and /dev/null differ diff --git a/_build/images/features/linear-algebra_45_0.png b/_build/images/features/linear-algebra_45_0.png deleted file mode 100644 index fe09c0a..0000000 Binary files a/_build/images/features/linear-algebra_45_0.png and /dev/null differ diff --git a/_build/images/features/linear-algebra_53_0.png b/_build/images/features/linear-algebra_53_0.png deleted file mode 100644 index 131c0d6..0000000 Binary files a/_build/images/features/linear-algebra_53_0.png and /dev/null differ diff --git a/_build/images/features/linear-algebra_55_0.png b/_build/images/features/linear-algebra_55_0.png deleted file mode 100644 index d5891e2..0000000 Binary files a/_build/images/features/linear-algebra_55_0.png and /dev/null differ diff --git a/_build/images/features/linear-algebra_84_0.png b/_build/images/features/linear-algebra_84_0.png deleted file mode 100644 index 2f57a65..0000000 Binary files a/_build/images/features/linear-algebra_84_0.png and /dev/null differ diff --git a/_build/images/features/linear-algebra_86_0.png b/_build/images/features/linear-algebra_86_0.png deleted file mode 100644 index b4ee8e6..0000000 Binary files a/_build/images/features/linear-algebra_86_0.png and /dev/null differ diff --git a/_build/images/features/linear-algebra_94_0.png b/_build/images/features/linear-algebra_94_0.png deleted file mode 100644 index 2f57a65..0000000 Binary files a/_build/images/features/linear-algebra_94_0.png and /dev/null differ diff --git a/_build/images/features/linear-algebra_96_0.png b/_build/images/features/linear-algebra_96_0.png deleted file mode 100644 index b4ee8e6..0000000 Binary files a/_build/images/features/linear-algebra_96_0.png and /dev/null differ diff --git a/_build/images/features/matplotlib_10_1.png b/_build/images/features/matplotlib_10_1.png deleted file mode 100644 index 82b2835..0000000 Binary files a/_build/images/features/matplotlib_10_1.png and /dev/null differ diff --git a/_build/images/features/matplotlib_11_0.png b/_build/images/features/matplotlib_11_0.png deleted file mode 100644 index 626d3b8..0000000 Binary files a/_build/images/features/matplotlib_11_0.png and /dev/null differ diff --git a/_build/images/features/matplotlib_11_1.png b/_build/images/features/matplotlib_11_1.png deleted file mode 100644 index d86536a..0000000 Binary files a/_build/images/features/matplotlib_11_1.png and /dev/null differ diff --git a/_build/images/features/matplotlib_12_0.png b/_build/images/features/matplotlib_12_0.png deleted file mode 100644 index 626d3b8..0000000 Binary files a/_build/images/features/matplotlib_12_0.png and /dev/null differ diff --git a/_build/images/features/matplotlib_12_1.png b/_build/images/features/matplotlib_12_1.png deleted file mode 100644 index cec12e2..0000000 Binary files a/_build/images/features/matplotlib_12_1.png and /dev/null differ diff --git a/_build/images/features/matplotlib_13_1.png b/_build/images/features/matplotlib_13_1.png deleted file mode 100644 index 6ccae92..0000000 Binary files a/_build/images/features/matplotlib_13_1.png and /dev/null differ diff --git a/_build/images/features/matplotlib_14_1.png b/_build/images/features/matplotlib_14_1.png deleted file mode 100644 index 215c338..0000000 Binary files a/_build/images/features/matplotlib_14_1.png and /dev/null differ diff --git a/_build/images/features/matplotlib_15_1.png b/_build/images/features/matplotlib_15_1.png deleted file mode 100644 index cec12e2..0000000 Binary files a/_build/images/features/matplotlib_15_1.png and /dev/null differ diff --git a/_build/images/features/matplotlib_16_1.png b/_build/images/features/matplotlib_16_1.png deleted file mode 100644 index cec12e2..0000000 Binary files a/_build/images/features/matplotlib_16_1.png and /dev/null differ diff --git a/_build/images/features/matplotlib_17_1.png b/_build/images/features/matplotlib_17_1.png deleted file mode 100644 index 6ccae92..0000000 Binary files a/_build/images/features/matplotlib_17_1.png and /dev/null differ diff --git a/_build/images/features/matplotlib_18_1.png b/_build/images/features/matplotlib_18_1.png deleted file mode 100644 index 215c338..0000000 Binary files a/_build/images/features/matplotlib_18_1.png and /dev/null differ diff --git a/_build/images/features/matplotlib_19_1.png b/_build/images/features/matplotlib_19_1.png deleted file mode 100644 index 4044290..0000000 Binary files a/_build/images/features/matplotlib_19_1.png and /dev/null differ diff --git a/_build/images/features/matplotlib_20_1.png b/_build/images/features/matplotlib_20_1.png deleted file mode 100644 index f55cbce..0000000 Binary files a/_build/images/features/matplotlib_20_1.png and /dev/null differ diff --git a/_build/images/features/matplotlib_21_0.png b/_build/images/features/matplotlib_21_0.png deleted file mode 100644 index cd9fd6d..0000000 Binary files a/_build/images/features/matplotlib_21_0.png and /dev/null differ diff --git a/_build/images/features/matplotlib_21_1.png b/_build/images/features/matplotlib_21_1.png deleted file mode 100644 index 948bfa2..0000000 Binary files a/_build/images/features/matplotlib_21_1.png and /dev/null differ diff --git a/_build/images/features/matplotlib_22_0.png b/_build/images/features/matplotlib_22_0.png deleted file mode 100644 index 7380059..0000000 Binary files a/_build/images/features/matplotlib_22_0.png and /dev/null differ diff --git a/_build/images/features/matplotlib_22_1.png b/_build/images/features/matplotlib_22_1.png deleted file mode 100644 index 374b90f..0000000 Binary files a/_build/images/features/matplotlib_22_1.png and /dev/null differ diff --git a/_build/images/features/matplotlib_24_1.png b/_build/images/features/matplotlib_24_1.png deleted file mode 100644 index c5451c7..0000000 Binary files a/_build/images/features/matplotlib_24_1.png and /dev/null differ diff --git a/_build/images/features/matplotlib_25_0.png b/_build/images/features/matplotlib_25_0.png deleted file mode 100644 index 7380059..0000000 Binary files a/_build/images/features/matplotlib_25_0.png and /dev/null differ diff --git a/_build/images/features/matplotlib_26_0.png b/_build/images/features/matplotlib_26_0.png deleted file mode 100644 index 3b9a165..0000000 Binary files a/_build/images/features/matplotlib_26_0.png and /dev/null differ diff --git a/_build/images/features/matplotlib_27_0.png b/_build/images/features/matplotlib_27_0.png deleted file mode 100644 index 7380059..0000000 Binary files a/_build/images/features/matplotlib_27_0.png and /dev/null differ diff --git a/_build/images/features/matplotlib_28_0.png b/_build/images/features/matplotlib_28_0.png deleted file mode 100644 index 421c624..0000000 Binary files a/_build/images/features/matplotlib_28_0.png and /dev/null differ diff --git a/_build/images/features/matplotlib_29_0.png b/_build/images/features/matplotlib_29_0.png deleted file mode 100644 index 7380059..0000000 Binary files a/_build/images/features/matplotlib_29_0.png and /dev/null differ diff --git a/_build/images/features/matplotlib_30_0.png b/_build/images/features/matplotlib_30_0.png deleted file mode 100644 index bc83020..0000000 Binary files a/_build/images/features/matplotlib_30_0.png and /dev/null differ diff --git a/_build/images/features/matplotlib_31_0.png b/_build/images/features/matplotlib_31_0.png deleted file mode 100644 index 3b9a165..0000000 Binary files a/_build/images/features/matplotlib_31_0.png and /dev/null differ diff --git a/_build/images/features/matplotlib_32_0.png b/_build/images/features/matplotlib_32_0.png deleted file mode 100644 index 137b169..0000000 Binary files a/_build/images/features/matplotlib_32_0.png and /dev/null differ diff --git a/_build/images/features/matplotlib_33_0.png b/_build/images/features/matplotlib_33_0.png deleted file mode 100644 index 3b9a165..0000000 Binary files a/_build/images/features/matplotlib_33_0.png and /dev/null differ diff --git a/_build/images/features/matplotlib_34_0.png b/_build/images/features/matplotlib_34_0.png deleted file mode 100644 index 3b9a165..0000000 Binary files a/_build/images/features/matplotlib_34_0.png and /dev/null differ diff --git a/_build/images/features/matplotlib_35_0.png b/_build/images/features/matplotlib_35_0.png deleted file mode 100644 index 137b169..0000000 Binary files a/_build/images/features/matplotlib_35_0.png and /dev/null differ diff --git a/_build/images/features/matplotlib_36_0.png b/_build/images/features/matplotlib_36_0.png deleted file mode 100644 index 421c624..0000000 Binary files a/_build/images/features/matplotlib_36_0.png and /dev/null differ diff --git a/_build/images/features/matplotlib_37_0.png b/_build/images/features/matplotlib_37_0.png deleted file mode 100644 index 58afb18..0000000 Binary files a/_build/images/features/matplotlib_37_0.png and /dev/null differ diff --git a/_build/images/features/matplotlib_38_0.png b/_build/images/features/matplotlib_38_0.png deleted file mode 100644 index b4a9f57..0000000 Binary files a/_build/images/features/matplotlib_38_0.png and /dev/null differ diff --git a/_build/images/features/matplotlib_8_1.png b/_build/images/features/matplotlib_8_1.png deleted file mode 100644 index 90f0b4f..0000000 Binary files a/_build/images/features/matplotlib_8_1.png and /dev/null differ diff --git a/_build/images/features/matplotlib_9_1.png b/_build/images/features/matplotlib_9_1.png deleted file mode 100644 index 70d6e97..0000000 Binary files a/_build/images/features/matplotlib_9_1.png and /dev/null differ diff --git a/_build/images/features/medium_modelling_part_one_10_0.png b/_build/images/features/medium_modelling_part_one_10_0.png deleted file mode 100644 index 942f839..0000000 Binary files a/_build/images/features/medium_modelling_part_one_10_0.png and /dev/null differ diff --git a/_build/images/features/numerical-calculus-integration-methods_10_1.png b/_build/images/features/numerical-calculus-integration-methods_10_1.png deleted file mode 100644 index 7773adb..0000000 Binary files a/_build/images/features/numerical-calculus-integration-methods_10_1.png and /dev/null differ diff --git a/_build/images/features/numerical-calculus-integration-methods_21_1.png b/_build/images/features/numerical-calculus-integration-methods_21_1.png deleted file mode 100644 index bcfee13..0000000 Binary files a/_build/images/features/numerical-calculus-integration-methods_21_1.png and /dev/null differ diff --git a/_build/images/features/numerical-calculus-integration-methods_23_1.png b/_build/images/features/numerical-calculus-integration-methods_23_1.png deleted file mode 100644 index bcfee13..0000000 Binary files a/_build/images/features/numerical-calculus-integration-methods_23_1.png and /dev/null differ diff --git a/_build/images/features/numerical-calculus-integration-methods_45_0.png b/_build/images/features/numerical-calculus-integration-methods_45_0.png deleted file mode 100644 index 50fc245..0000000 Binary files a/_build/images/features/numerical-calculus-integration-methods_45_0.png and /dev/null differ diff --git a/_build/images/features/numerical-calculus-integration-methods_47_0.png b/_build/images/features/numerical-calculus-integration-methods_47_0.png deleted file mode 100644 index fd8912c..0000000 Binary files a/_build/images/features/numerical-calculus-integration-methods_47_0.png and /dev/null differ diff --git a/_build/images/features/numerical-calculus-integration_31_0.png b/_build/images/features/numerical-calculus-integration_31_0.png deleted file mode 100644 index 3cdc175..0000000 Binary files a/_build/images/features/numerical-calculus-integration_31_0.png and /dev/null differ diff --git a/_build/images/features/numerical-calculus-integration_32_0.png b/_build/images/features/numerical-calculus-integration_32_0.png deleted file mode 100644 index 9079022..0000000 Binary files a/_build/images/features/numerical-calculus-integration_32_0.png and /dev/null differ diff --git a/_build/images/features/numerical-calculus_102_1.png b/_build/images/features/numerical-calculus_102_1.png deleted file mode 100644 index 9e2eb19..0000000 Binary files a/_build/images/features/numerical-calculus_102_1.png and /dev/null differ diff --git a/_build/images/features/numerical-calculus_106_1.png b/_build/images/features/numerical-calculus_106_1.png deleted file mode 100644 index 8a09e5a..0000000 Binary files a/_build/images/features/numerical-calculus_106_1.png and /dev/null differ diff --git a/_build/images/features/numerical-calculus_107_1.png b/_build/images/features/numerical-calculus_107_1.png deleted file mode 100644 index 8a09e5a..0000000 Binary files a/_build/images/features/numerical-calculus_107_1.png and /dev/null differ diff --git a/_build/images/features/numerical-calculus_111_1.png b/_build/images/features/numerical-calculus_111_1.png deleted file mode 100644 index 8a09e5a..0000000 Binary files a/_build/images/features/numerical-calculus_111_1.png and /dev/null differ diff --git a/_build/images/features/numerical-calculus_12_1.png b/_build/images/features/numerical-calculus_12_1.png deleted file mode 100644 index e2225eb..0000000 Binary files a/_build/images/features/numerical-calculus_12_1.png and /dev/null differ diff --git a/_build/images/features/numerical-calculus_73_0.png b/_build/images/features/numerical-calculus_73_0.png deleted file mode 100644 index 7a5d38d..0000000 Binary files a/_build/images/features/numerical-calculus_73_0.png and /dev/null differ diff --git a/_build/images/features/numerical-calculus_74_0.png b/_build/images/features/numerical-calculus_74_0.png deleted file mode 100644 index 7a5d38d..0000000 Binary files a/_build/images/features/numerical-calculus_74_0.png and /dev/null differ diff --git a/_build/images/features/numerical-calculus_75_1.png b/_build/images/features/numerical-calculus_75_1.png deleted file mode 100644 index 7c7d977..0000000 Binary files a/_build/images/features/numerical-calculus_75_1.png and /dev/null differ diff --git a/_build/images/features/numerical-calculus_76_1.png b/_build/images/features/numerical-calculus_76_1.png deleted file mode 100644 index 7c7d977..0000000 Binary files a/_build/images/features/numerical-calculus_76_1.png and /dev/null differ diff --git a/_build/images/features/numerical-calculus_86_1.png b/_build/images/features/numerical-calculus_86_1.png deleted file mode 100644 index 12c05bc..0000000 Binary files a/_build/images/features/numerical-calculus_86_1.png and /dev/null differ diff --git a/_build/images/features/numerical-calculus_87_1.png b/_build/images/features/numerical-calculus_87_1.png deleted file mode 100644 index 12c05bc..0000000 Binary files a/_build/images/features/numerical-calculus_87_1.png and /dev/null differ diff --git a/_build/images/features/numerical-calculus_97_1.png b/_build/images/features/numerical-calculus_97_1.png deleted file mode 100644 index 9e2eb19..0000000 Binary files a/_build/images/features/numerical-calculus_97_1.png and /dev/null differ diff --git a/_build/images/features/numerical-calculus_98_1.png b/_build/images/features/numerical-calculus_98_1.png deleted file mode 100644 index 9e2eb19..0000000 Binary files a/_build/images/features/numerical-calculus_98_1.png and /dev/null differ diff --git a/_build/images/features/one-variable-equations-fixed-point_24_2.png b/_build/images/features/one-variable-equations-fixed-point_24_2.png deleted file mode 100644 index a1acabd..0000000 Binary files a/_build/images/features/one-variable-equations-fixed-point_24_2.png and /dev/null differ diff --git a/_build/images/features/one-variable-equations-fixed-point_25_2.png b/_build/images/features/one-variable-equations-fixed-point_25_2.png deleted file mode 100644 index a1acabd..0000000 Binary files a/_build/images/features/one-variable-equations-fixed-point_25_2.png and /dev/null differ diff --git a/_build/images/features/one-variable-equations-fixed-point_26_2.png b/_build/images/features/one-variable-equations-fixed-point_26_2.png deleted file mode 100644 index cfe93b7..0000000 Binary files a/_build/images/features/one-variable-equations-fixed-point_26_2.png and /dev/null differ diff --git a/_build/images/features/one-variable-equations-fixed-point_33_2.png b/_build/images/features/one-variable-equations-fixed-point_33_2.png deleted file mode 100644 index e5eddbb..0000000 Binary files a/_build/images/features/one-variable-equations-fixed-point_33_2.png and /dev/null differ diff --git a/_build/images/features/one-variable-equations-fixed-point_42_0.png b/_build/images/features/one-variable-equations-fixed-point_42_0.png deleted file mode 100644 index 3dc44dc..0000000 Binary files a/_build/images/features/one-variable-equations-fixed-point_42_0.png and /dev/null differ diff --git a/_build/images/features/one-variable-equations-fixed-point_43_0.png b/_build/images/features/one-variable-equations-fixed-point_43_0.png deleted file mode 100644 index 3dc44dc..0000000 Binary files a/_build/images/features/one-variable-equations-fixed-point_43_0.png and /dev/null differ diff --git a/_build/images/features/one-variable-equations-fixed-point_47_2.png b/_build/images/features/one-variable-equations-fixed-point_47_2.png deleted file mode 100644 index 79cd973..0000000 Binary files a/_build/images/features/one-variable-equations-fixed-point_47_2.png and /dev/null differ diff --git a/_build/images/features/one-variable-equations-fixed-point_48_2.png b/_build/images/features/one-variable-equations-fixed-point_48_2.png deleted file mode 100644 index 79cd973..0000000 Binary files a/_build/images/features/one-variable-equations-fixed-point_48_2.png and /dev/null differ diff --git a/_build/images/features/one-variable-equations-fixed-point_62_2.png b/_build/images/features/one-variable-equations-fixed-point_62_2.png deleted file mode 100644 index e19e5be..0000000 Binary files a/_build/images/features/one-variable-equations-fixed-point_62_2.png and /dev/null differ diff --git a/_build/images/features/one-variable-equations-fixed-point_63_2.png b/_build/images/features/one-variable-equations-fixed-point_63_2.png deleted file mode 100644 index e19e5be..0000000 Binary files a/_build/images/features/one-variable-equations-fixed-point_63_2.png and /dev/null differ diff --git a/_build/images/features/one-variable-equations-fixed-point_82_0.png b/_build/images/features/one-variable-equations-fixed-point_82_0.png deleted file mode 100644 index 709603a..0000000 Binary files a/_build/images/features/one-variable-equations-fixed-point_82_0.png and /dev/null differ diff --git a/_build/images/features/one-variable-equations-fixed-point_88_0.png b/_build/images/features/one-variable-equations-fixed-point_88_0.png deleted file mode 100644 index 51f7fb8..0000000 Binary files a/_build/images/features/one-variable-equations-fixed-point_88_0.png and /dev/null differ diff --git a/_build/images/features/one-variable-equations-fixed-point_89_0.png b/_build/images/features/one-variable-equations-fixed-point_89_0.png deleted file mode 100644 index 51f7fb8..0000000 Binary files a/_build/images/features/one-variable-equations-fixed-point_89_0.png and /dev/null differ diff --git a/_build/images/features/one-variable-equations-fixed-point_98_0.png b/_build/images/features/one-variable-equations-fixed-point_98_0.png deleted file mode 100644 index 51f7fb8..0000000 Binary files a/_build/images/features/one-variable-equations-fixed-point_98_0.png and /dev/null differ diff --git a/_build/images/features/one-variable-equations_17_1.png b/_build/images/features/one-variable-equations_17_1.png deleted file mode 100644 index 189dae1..0000000 Binary files a/_build/images/features/one-variable-equations_17_1.png and /dev/null differ diff --git a/_build/images/features/one-variable-equations_18_0.png b/_build/images/features/one-variable-equations_18_0.png deleted file mode 100644 index 688bca8..0000000 Binary files a/_build/images/features/one-variable-equations_18_0.png and /dev/null differ diff --git a/_build/images/features/one-variable-equations_18_1.png b/_build/images/features/one-variable-equations_18_1.png deleted file mode 100644 index 189dae1..0000000 Binary files a/_build/images/features/one-variable-equations_18_1.png and /dev/null differ diff --git a/_build/images/features/one-variable-equations_19_0.png b/_build/images/features/one-variable-equations_19_0.png deleted file mode 100644 index 688bca8..0000000 Binary files a/_build/images/features/one-variable-equations_19_0.png and /dev/null differ diff --git a/_build/images/features/one-variable-equations_19_1.png b/_build/images/features/one-variable-equations_19_1.png deleted file mode 100644 index 189dae1..0000000 Binary files a/_build/images/features/one-variable-equations_19_1.png and /dev/null differ diff --git a/_build/images/features/one-variable-equations_20_0.png b/_build/images/features/one-variable-equations_20_0.png deleted file mode 100644 index 688bca8..0000000 Binary files a/_build/images/features/one-variable-equations_20_0.png and /dev/null differ diff --git a/_build/images/features/one-variable-equations_21_1.png b/_build/images/features/one-variable-equations_21_1.png deleted file mode 100644 index 5eaab61..0000000 Binary files a/_build/images/features/one-variable-equations_21_1.png and /dev/null differ diff --git a/_build/images/features/one-variable-equations_22_0.png b/_build/images/features/one-variable-equations_22_0.png deleted file mode 100644 index c41468b..0000000 Binary files a/_build/images/features/one-variable-equations_22_0.png and /dev/null differ diff --git a/_build/images/features/one-variable-equations_79_2.png b/_build/images/features/one-variable-equations_79_2.png deleted file mode 100644 index 95d9031..0000000 Binary files a/_build/images/features/one-variable-equations_79_2.png and /dev/null differ diff --git a/_build/images/features/one-variable-equations_80_2.png b/_build/images/features/one-variable-equations_80_2.png deleted file mode 100644 index 33ca1bb..0000000 Binary files a/_build/images/features/one-variable-equations_80_2.png and /dev/null differ diff --git a/_build/images/features/one-variable-equations_82_2.png b/_build/images/features/one-variable-equations_82_2.png deleted file mode 100644 index 33ca1bb..0000000 Binary files a/_build/images/features/one-variable-equations_82_2.png and /dev/null differ diff --git a/_build/images/features/one-variable-equations_92_2.png b/_build/images/features/one-variable-equations_92_2.png deleted file mode 100644 index 95d9031..0000000 Binary files a/_build/images/features/one-variable-equations_92_2.png and /dev/null differ diff --git a/_build/images/features/one-variable-equations_96_2.png b/_build/images/features/one-variable-equations_96_2.png deleted file mode 100644 index 95d9031..0000000 Binary files a/_build/images/features/one-variable-equations_96_2.png and /dev/null differ diff --git a/_build/images/features/statistics_100_1.png b/_build/images/features/statistics_100_1.png deleted file mode 100644 index 53ca6e8..0000000 Binary files a/_build/images/features/statistics_100_1.png and /dev/null differ diff --git a/_build/images/features/statistics_103_1.png b/_build/images/features/statistics_103_1.png deleted file mode 100644 index 21bfa04..0000000 Binary files a/_build/images/features/statistics_103_1.png and /dev/null differ diff --git a/_build/images/features/statistics_20_0.png b/_build/images/features/statistics_20_0.png deleted file mode 100644 index ae49b3d..0000000 Binary files a/_build/images/features/statistics_20_0.png and /dev/null differ diff --git a/_build/images/features/statistics_30_0.png b/_build/images/features/statistics_30_0.png deleted file mode 100644 index 483538a..0000000 Binary files a/_build/images/features/statistics_30_0.png and /dev/null differ diff --git a/_build/images/features/statistics_37_1.png b/_build/images/features/statistics_37_1.png deleted file mode 100644 index d05539c..0000000 Binary files a/_build/images/features/statistics_37_1.png and /dev/null differ diff --git a/_build/images/features/statistics_39_1.png b/_build/images/features/statistics_39_1.png deleted file mode 100644 index d05539c..0000000 Binary files a/_build/images/features/statistics_39_1.png and /dev/null differ diff --git a/_build/images/features/statistics_41_0.png b/_build/images/features/statistics_41_0.png deleted file mode 100644 index 630302c..0000000 Binary files a/_build/images/features/statistics_41_0.png and /dev/null differ diff --git a/_build/images/features/statistics_43_0.png b/_build/images/features/statistics_43_0.png deleted file mode 100644 index c56d3e5..0000000 Binary files a/_build/images/features/statistics_43_0.png and /dev/null differ diff --git a/_build/images/features/statistics_50_0.png b/_build/images/features/statistics_50_0.png deleted file mode 100644 index bebe1bd..0000000 Binary files a/_build/images/features/statistics_50_0.png and /dev/null differ diff --git a/_build/images/features/statistics_52_0.png b/_build/images/features/statistics_52_0.png deleted file mode 100644 index 502fc48..0000000 Binary files a/_build/images/features/statistics_52_0.png and /dev/null differ diff --git a/_build/images/features/statistics_58_1.png b/_build/images/features/statistics_58_1.png deleted file mode 100644 index c5065f8..0000000 Binary files a/_build/images/features/statistics_58_1.png and /dev/null differ diff --git a/_build/images/features/statistics_60_1.png b/_build/images/features/statistics_60_1.png deleted file mode 100644 index 704ae75..0000000 Binary files a/_build/images/features/statistics_60_1.png and /dev/null differ diff --git a/_build/images/features/statistics_88_1.png b/_build/images/features/statistics_88_1.png deleted file mode 100644 index 6ab71dc..0000000 Binary files a/_build/images/features/statistics_88_1.png and /dev/null differ diff --git a/_build/images/features/statistics_91_1.png b/_build/images/features/statistics_91_1.png deleted file mode 100644 index 99ac1c4..0000000 Binary files a/_build/images/features/statistics_91_1.png and /dev/null differ diff --git a/_build/images/features/statistics_93_1.png b/_build/images/features/statistics_93_1.png deleted file mode 100644 index 71a3050..0000000 Binary files a/_build/images/features/statistics_93_1.png and /dev/null differ diff --git a/_build/images/features/statistics_95_1.png b/_build/images/features/statistics_95_1.png deleted file mode 100644 index 4af13cf..0000000 Binary files a/_build/images/features/statistics_95_1.png and /dev/null differ diff --git a/_build/images/features/statistics_96_1.png b/_build/images/features/statistics_96_1.png deleted file mode 100644 index 9382695..0000000 Binary files a/_build/images/features/statistics_96_1.png and /dev/null differ diff --git a/_build/images/features/statistics_97_1.png b/_build/images/features/statistics_97_1.png deleted file mode 100644 index 1f12e43..0000000 Binary files a/_build/images/features/statistics_97_1.png and /dev/null differ diff --git a/_build/images/features/statistics_98_1.png b/_build/images/features/statistics_98_1.png deleted file mode 100644 index 04dfc43..0000000 Binary files a/_build/images/features/statistics_98_1.png and /dev/null differ diff --git a/_build/images/logo/download.svg b/_build/images/logo/download.svg deleted file mode 100755 index ab25508..0000000 --- a/_build/images/logo/download.svg +++ /dev/null @@ -1,90 +0,0 @@ - -Group.svg -Created using Figma 0.90 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/_build/images/logo/favicon.ico b/_build/images/logo/favicon.ico deleted file mode 100755 index eb2cf42..0000000 Binary files a/_build/images/logo/favicon.ico and /dev/null differ diff --git a/_build/images/logo/jupyter.png b/_build/images/logo/jupyter.png deleted file mode 100755 index 8fed260..0000000 Binary files a/_build/images/logo/jupyter.png and /dev/null differ diff --git a/_build/images/logo/logo.png b/_build/images/logo/logo.png deleted file mode 100755 index eb2cf42..0000000 Binary files a/_build/images/logo/logo.png and /dev/null differ diff --git a/_build/images/logo/logo.psd b/_build/images/logo/logo.psd deleted file mode 100755 index d6ad942..0000000 Binary files a/_build/images/logo/logo.psd and /dev/null differ diff --git a/_build/index.html b/_build/index.html deleted file mode 100644 index a99b455..0000000 --- a/_build/index.html +++ /dev/null @@ -1,482 +0,0 @@ ---- -interact_link: content/index.ipynb -kernel_name: python3 -kernel_path: content -has_widgets: false -title: |- - Introduction -pagenum: 0 -prev_page: - url: -next_page: - url: /features/overview-python.html -suffix: .ipynb -search: com github ipynb material computationalmethods restrepo master blob br python numerical view google computational physics pdf linear methods equations drive topics file interpolation d usp sharing www colab course integration algebra ipython point science notebooks variable method calculus org research open programming repository weeks fixed differential order gd display astronomy io problems notes scientific data interpolationdetails matrix computation lecture edu html bar sbustamante also week git overview libraries analysis activities techniques lagrange divided differences hermite minimization jupyter systems statistics scipy introduction john f guide lilith fisica ufmg dickman transfers comp textos engineering jupyterpython ac uk modules install jsanimation href index - -comment: "***PROGRAMMATICALLY GENERATED, DO NOT EDIT. SEE ORIGINAL FILES IN /content***" ---- - -
-
Introduction
-
-
- -
-
-

Open In Colab

- -
-
-
-
- -
- -
-
-

To open in Colab use the previous button or replace in the address bar:

- -
github.com → colab.research.google.com/github
-

Computational Methods for Physics & Astronomy

Book version:

https://restrepo.github.io/ComputationalMethods/

-

by: Sebastian Bustamante 2014/2015 Diego Restrepo 2017...

-

-

This course is intended for students of Astronomy and Physics at the Universidad de Antioquia -and will cover some numerical methods commonly used in science and specially in physics ans astronomy. These topics will be addressed from a formal context but also keeping -a practical and computational approach, illustrating many useful applications in -problems of physics and astronomy.

-

The practical component will be almost entirely developed in Python and -slightly less in C (when computational performance is required). -However students with knowledge in other programming languages (except -privative languages like MatLab, Mathematica) are also aimed to use them.

-

In this repository it can be found all the related material of the course, -including the detailed program, notes and presentations, examples (ipython -notebooks) and homeworks. (This repository may be subject to changes continuously -as the course advances).

-

Instructions to use the repository

    -
  • Use the Colab button to open the reposotry in an executable enviroment
  • -
  • To save changes:
      -
    1. FileDownload .ipynb
    2. -
    3. Open a repository in GitHub and Upload the file
    4. -
    5. To open again in Colab replace in the address bar: github.com → colab.research.google.com/github
    6. -
    -
  • -
-

SYLLABUS: -detailed description of the program of the course, including a brief motivation and presentation, -topics to be covered, evaluation and bibliography.

-

Contents

1. Python (1 week)

Topics

- -

Processing

- -

Data analysis

- -

Visualization

- -

Activities

-
    -
  • Activity 01: Solve the problems in the section Exercises.
  • -
-

2. Mathematical Preliminaries (1 week)

Topics

- -

3. One Variable Equations (2 weeks)

./one-variable-equations.ipynb -Topics

- -

4. Interpolation Techniques (2 weeks)

Topics

- -

5. Numerical Calculus (2 weeks)

Topics

- -

Activities

- -

6. Linear Algebra (2 weeks)

Topics

- -

7. Differential Equations (2 weeks)

Topics

- -

8. Statistics (1 week)

Topics

- -

9. Extra material (1 session)

Topics

- - -
-
-
-
- -
- -
-
-

Bibliography

[1a] Gonzalo Galiano Casas, Esperanza García Gonzalo Numerical Computation - GD - Web page with notebooks
-[1b] Scipy Lecture Notes [PDF]
-[1b] Jensen, Computational_Physics. GitHub
-[1d] Introduction to computational physics
-[1e] Thomas J. Sargent John Stachurski, Python Programming for Quantitative Economics -GitHub
-[1f] Ani Adhikari and John DeNero, Computational and Inferential Thinking
-[1g] Mo Mu, MATH 3311: Introduction to Numerical Methods GD
-[1h] Zhiliang Xu, ACMS 40390: Fall 2016 - Numerical Analysis GD</br> -[1f] Computational Physiscs, University of Toronto https://computation.physics.utoronto.ca/
-[1g] Simon Sirca, Computational Methods for Physicists GD
-[1h] Anthony Scopatz and Kathryn D. Huff, Effective Computation in Physics: Field Guide to Research with Python PDF.pdf) GD
-[1i] Tao Pang, An Introduction to Computational Physics PDF.pdf)
-[2] Landau Paez, A Survey of Computational Physics
-[3] Kiusalaas, Numerical Methods in Engineering with Python
-[4] Sørenssen Elementary Mechanics Using Python A Modern Course Combining Analytical and Numerical Techniques
-[5] Langtangen_Python_Scripting_for_Computational_Science_3rd_edition
-[6] Python programming standards Repository: https://github.com/kennethreitz/python-guide)
-[7] Lecture notes Course Numerical Analysis (MatLab)
-[8] Jupyter+Python: Python in Science
-[9] Jupyter+Python: Python for Computational Science and Engineering PDF Notebooks
-[10] Jupyter+Python: Scientific Computing and Simulation
-[11] E. Ayres, Computational Physics With Python
-[12] Hans Petter Langtangen A worked example on scientific computing with Python
-[12] By Ani Adhikari and John DeNero Computational and Inferential Thinking
-13] By Sam Lau, Joey Gonzalez, and Deb Nolan. DS100 Principles and Techniques of Data Science
-[14] Software Design and Development: The Preliminary Course, – January 1, 2002, by Samuel Davis (Author) [PDF]
-[15] Bradley Voytek, et al, Data Science in Practice
-[16] P. DeVries, A First Course in Computational Physics PDF

- -
-
-
-
- -
- -
-
-

Appendix

General configuration modules. It is recommended to use the following magic command to load all the plotting capabilities of python (also load numpy as np) and display

- -
-
-
-
- -
- -
-
- -
-
-
%pylab inline
-
- -
-
-
- -
-
- -
-
- -
-
Populating the interactive namespace from numpy and matplotlib
-
-
-
-
-
-
- -
-
- -
- -
-
-

Some times it is convenient to have advance display capabilities in the evaluation cells. It is possible with the module Ipython.display. To have multiple special outputs in the same cell, it is necessary to use the display function loaded with %pylab inline

- -
-
-
-
- -
- -
-
- -
-
-
from IPython.display import Math, Latex, HTML, JSON , Markdown, YouTubeVideo
-
- -
-
-
- -
-
- -
- -
-
- -
-
-
HTML('<h1>Hola mundo</h1>')
-
- -
-
-
- -
-
- -
-
- - -
-

Hola mundo

-
- -
-
-
-
- -
-
- -
- -
-
- -
-
-
display( HTML('<h1>Hola mundo</h1>') ) 
-display( Math(' \int \sin x\, d x') )
-print('multiple and mixed print with display(..)')
-
- -
-
-
- -
-
- -
-
- - -
-

Hola mundo

-
- -
-
-
-
- - - -
-$$ \int \sin x\, d x$$ -
- -
-
-
-
- -
-
multiple and mixed print with display(..)
-
-
-
-
-
-
- -
-
- -
- -
-
-

LaTeX is fully supported (see: https://stackoverflow.com/a/44375719/2268280)

- -
-
-
-
- -
- -
-
-

Requirements

    -
  • Modules installed with pip(3)
  • -
- -
-
-
-
- -
- -
-
- -
-
-
%%writefile requirements.txt
-sympy
-ipywidgets
-
- -
-
-
- -
-
- -
-
- -
-
Writing requirements.txt
-
-
-
-
-
-
- -
-
- -
- -
-
- -
-
-
%%writefile postBuild
-jupyter nbextension enable --py widgetsnbextension
-
- -
-
-
- -
-
- -
-
- -
-
Writing postBuild
-
-
-
-
-
-
- -
-
- -
- -
-
- - -
-
-
-
- -
- -
-
-

Recomended libraries for final projects

- -
-
-
-
- - - - -
- \ No newline at end of file diff --git a/_config.yml b/_config.yml old mode 100755 new mode 100644 index d9e2e62..014563f --- a/_config.yml +++ b/_config.yml @@ -1,161 +1,34 @@ -# Welcome to Jekyll! -# -# This config file is meant for settings that affect your whole blog, values -# which you are expected to set up once and rarely edit after that. If you find -# yourself editing this file very often, consider using Jekyll's data files -# feature for the data you need to update frequently. -# -# For technical reasons, this file is *NOT* reloaded automatically when you use -# 'bundle exec jekyll serve'. If you change this file, please restart the server process. - -# Site settings -# These are used to personalize your new site. If you look in the HTML files, -# you will see them accessed via {{ site.title }}, {{ site.email }}, and so on. -# You can create any custom variable you would like, and they will be accessible -# in the templates via {{ site.myvariable }}. - -####################################################################################### -# Jekyll site settings -title: Computational methods -author: Sebastian Bustamante, Diego Restrepo -email: restrepo@udea.edu.co -description: >- - Numerical methods commonly used in science - -baseurl: / # the subpath of your site, e.g. /blog. If there is no subpath for your site, use an empty string "" -url: https://restrepo.github.io/ComputationalMethods # the base hostname & protocol for your site, e.g. http://example.com - - -####################################################################################### -# Jupyter Book settings - -# Main page settings -footer_text: This page was created by The - Jupyter Book Community - -# Sidebar settings -show_sidebar: true # Show the sidebar. Only set to false if your only wish to host a single page. -collapse_inactive_chapters: true # Whether to collapse the inactive chapters in the sidebar -collapse_inactive_sections: true # Whether to collapse the sub-sections within a non-active section in the sidebar -textbook_logo: images/logo/logo.png # A logo to be displayed at the top of your textbook sidebar. Should be square -textbook_logo_link: https://jupyterbook.org/ # A link for the logo. -sidebar_footer_text: Powered by Jupyter Book -number_toc_chapters: true # Whether to add numbers to chapterse in your Table of Contents. If true, you can control this at the Chapter level in _data/toc.yml - -# Search settings -search_max_words_in_content: 100 # In the search function, use at most this many words (too many words will make search slow) - -# Controlling page information -page_titles: infer # Either `None`, `infer`, or `toc` -page_authors: None # Either `None` or `infer` -filename_title_split_character: _ # If inferring titles based on filename, splt on this character. - -# Math settings -number_equations: false # Whether to automatically number all block equations with MathJax - -####################################################################################### -# Interact link settings - -# General interact settings -use_jupyterlab: false # If 'true', interact links will use JupyterLab as the interface - -# Jupyterhub link settings -use_jupyterhub_button: false # If 'true', display a button that will direct users to a JupyterHub (that you provide) -jupyterhub_url: '' # The URL for your JupyterHub. If no URL, use "" -jupyterhub_interact_text: Interact # The text that interact buttons will contain. - -# Binder link settings -use_binder_button: true # If 'true', add a binder button for interactive links -binderhub_url: https://mybinder.org # The URL for your BinderHub. If no URL, use "" -binder_repo_base: https://github.com/ # The site on which the textbook repository is hosted -binder_repo_org: restrepo # The username or organization that owns this repository -binder_repo_name: ComputationalMethods # The name of the repository on the web -binder_repo_branch: master # The branch on which your textbook is hosted. -binderhub_interact_text: Interact # The text that interact buttons will contain. - -# Thebelab settings -use_thebelab_button: true # If 'true', display a button to allow in-page running code cells with Thebelab -thebelab_button_text: Thebelab # The text to display inside the Thebelab initialization button -codemirror_theme: abcdef # Theme for codemirror cells, for options see https://codemirror.net/doc/manual.html#config - -# nbinteract settings -use_show_widgets_button: true # If 'true', display a button to allow in-page running code cells with nbinteract - -# Download settings -use_download_button: true # If 'true', display a button to download a zip file for the notebook -download_button_text: Download # The text that download buttons will contain -download_page_header: Made with Jupyter Book # A header that will be displayed at the top of and PDF-printed page - -####################################################################################### -# Jupyter book extensions and additional features - -# Bibliography and citation settings. See https://github.com/inukshuk/jekyll-scholar#configuration for options -scholar: - style: apa - -####################################################################################### -# Option to add a Goggle analytics tracking code - -# Navigate to https://analytics.google.com, add a new property for your jupyter book and copy the tracking id here. -google_analytics: - mytrackingcode: '' - -####################################################################################### -# Jupyter book settings you probably don't need to change - -content_folder_name: content # The folder where your raw content (notebooks/markdown files) are located -images_url: /assets/images # Path to static image files -css_url: /assets/css # Path to static CSS files -js_url: /assets/js # Path to JS files -custom_static_url: /assets/custom # Path to user's custom CSS/JS files - - -####################################################################################### -# Jekyll build settings (only modify if you know what you're doing) - -# Site settings -defaults: -- scope: - path: '' - values: - layout: default - toc: true - toc_label: ' On this page' - toc_icon: list-ul - excerpt: '' - -favicon_path: images/logo/favicon.ico - -# Markdown Processing -markdown: kramdown -kramdown: - input: GFM - syntax_highlighter: rouge - -sass: - style: compressed - -collections: - build: - output: true - permalink: /:path.html - -# Exclude from processing. -# The following items will not be processed, by default. Create a custom list -# to override the default setting. -exclude: -- scripts/ -- Gemfile -- Gemfile.lock -- node_modules -- vendor/bundle/ -- vendor/cache/ -- vendor/gems/ -- vendor/ruby/ - -plugins: -- jekyll-redirect-from -- jekyll-scholar - -# Jupyter Book version - DO NOT CHANGE THIS. It is generated when a new book is created -jupyter_book_version: 0.6.4 +# Book settings +# Learn more at https://jupyterbook.org/customize/config.html + +title: Computational Methods +author: Diego Restrepo (UdeA) +logo: logo.png + +# Force re-execution of notebooks on each build. +# See https://jupyterbook.org/content/execute.html +execute: + execute_notebooks: 'off' + +# Define the name of the latex output file for PDF builds +latex: + latex_documents: + targetname: book.tex + +# Add a bibtex file so that we can create citations +bibtex_bibfiles: + - references.bib + +# Information about where the book exists on the web +repository: + url: https://github.com/restrepo/ComputationalMethods # Online location of your book + path_to_book: docs # Optional path to your book, relative to the repository root + branch: master # Which branch of the repository should be used when creating links (optional) + +# Add GitHub buttons to your book +# See https://jupyterbook.org/customize/config.html#add-a-link-to-your-repository +html: + use_issues_button: true + use_repository_button: true + +only_build_toc_files: true \ No newline at end of file diff --git a/_data/toc.yml b/_data/toc.yml deleted file mode 100755 index 8b72507..0000000 --- a/_data/toc.yml +++ /dev/null @@ -1,137 +0,0 @@ -# This file contains the order and numbering for all sections in the book. -# -# It is a sample TOC file to help you get started. Fill it out with entries -# for your own content. -# -# Each entry has the following schema: -# -# - title: mytitle # Title of chapter or section -# url: /myurl # URL of section relative to the /content/ folder. -# sections: # Contains a list of more entries that make up the chapter's sections -# not_numbered: true # if the section shouldn't have a number in the sidebar -# (e.g. Introduction or appendices) -# expand_sections: true # if you'd like the sections of this chapter to always -# be expanded in the sidebar. -# external: true # Whether the URL is an external link or points to content in the book -# -# Below are some special values that trigger specific behavior: -# - search: true # Will provide a link to a search page -# - divider: true # Will insert a divider in the sidebar -# - header: My Header # Will insert a header with no link in the sidebar -# -# See the links below for an example. - -# Top-level page -- title: Introduction - url: /index - not_numbered: true - -# Divider for meta-pages and content page -- divider: true - -# Add a header and sample content section -- header: Contents - -# A chapter w/ a collection of sections beneath it -- title: Python overview - url: /features/overview-python - not_numbered: false - expand_sections: false - sections: - - title: Scientific libraries - url: /features/scientific-libraries - not_numbered: false - - title: Data analysis with Pandas - url: /features/Pandas - not_numbered: false - - title: Visualization with matplotlib - url: /features/matplotlib - not_numbered: false - - title: Interactive editing with Jupyter - url: /features/ipython-notebooks - not_numbered: false - -- title: Mathematical Preliminaries - url: /features/computer-arithmetics - not_numbered: false - expand_sections: false - sections: - - title: Algorithms and convergence - url: /features/algorithms-convergence - not_numbered: false - - title: Optimization - url: /features/numba - not_numbered: false - -- title: One Variable Equations - url: /features/one-variable-equations - not_numbered: false - expand_sections: false - sections: - - title: Fixed point - url: /features/one-variable-equations-fixed-point - not_numbered: false - -- title: Interpolation - url: /features/interpolation - not_numbered: false - expand_sections: false - sections: - - title: Lagrange polynomials - url: /features/LagrangePoly - not_numbered: false - - title: Hemite interpolation - url: /features/interpolation_details - not_numbered: false - - title: Minimization - url: /features/Minimization - not_numbered: false - - title: Minimization for Least Action - url: /features/least_action_minimization - not_numbered: false - -- title: Numerical calculus - url: /features/numerical-calculus - not_numbered: false - expand_sections: false - sections: - - title: Numerical integration - url: /features/numerical-calculus-integration - not_numbered: false - - title: Numerical integration - url: /features/numerical-calculus-integration - not_numbered: false - - title: Numerical integration methods - url: /features/numerical-calculus-integration-methods - not_numbered: false - -- title: Linear algebra - url: /features/linear-algebra - not_numbered: false - expand_sections: false - sections: - - title: Matriz diagonalization - url: /features/linear-algebra-diagonalization - not_numbered: false - - title: Custum Gaussian elimination - url: /features/linear-algebra-extra - not_numbered: false - -- title: Diferential equations - url: /features/differential-equations - not_numbered: false - expand_sections: false - sections: - - title: SIR Model - url: /features/medium_modelling_part_one - not_numbered: false - -- title: Statistics - url: /features/statistics - not_numbered: false - expand_sections: false - -- title: Clases - url: /features/Intro_clases - not_numbered: false - expand_sections: false diff --git a/_includes/buttons.html b/_includes/buttons.html deleted file mode 100755 index 03b36c4..0000000 --- a/_includes/buttons.html +++ /dev/null @@ -1,9 +0,0 @@ -
-{% include buttons/download.html %} -{% if page.interact_link %} - {% include buttons/thebelab.html %} - {% include buttons/nbinteract.html %} - {% include buttons/binder.html %} - {% include buttons/jupyterhub.html %} -{% endif %} -
diff --git a/_includes/buttons/binder.html b/_includes/buttons/binder.html deleted file mode 100755 index c9577f1..0000000 --- a/_includes/buttons/binder.html +++ /dev/null @@ -1,14 +0,0 @@ -{% if site.use_binder_button %} - -{% if site.use_jupyterlab %} - {% assign binder_interact_prefix="urlpath=lab/tree/" %} -{% else %} - {% assign binder_interact_prefix="filepath=" %} -{% endif %} - -{% capture interact_url_binder %}v2/gh/{{ site.binder_repo_org }}/{{ site.binder_repo_name }}/{{ site.binder_repo_branch }}?{{ binder_interact_prefix }}{{ page.interact_link | url_encode }}{% endcapture %} -{% capture interact_icon_binder %}{{ site.images_url | relative_url }}/logo_binder.svg{% endcapture %} - - - -{%- endif %} \ No newline at end of file diff --git a/_includes/buttons/download.html b/_includes/buttons/download.html deleted file mode 100755 index 190f011..0000000 --- a/_includes/buttons/download.html +++ /dev/null @@ -1,13 +0,0 @@ -{% if site.use_download_button -%} -
- -
- {% if page.interact_link -%} - - - - {% endif %} - -
-
-{%- endif %} diff --git a/_includes/buttons/jupyterhub.html b/_includes/buttons/jupyterhub.html deleted file mode 100755 index 8e17d31..0000000 --- a/_includes/buttons/jupyterhub.html +++ /dev/null @@ -1,13 +0,0 @@ -{% if site.use_jupyterhub_button %} - -{% if site.use_jupyterlab %} - {% assign hub_app="lab" %} -{% else %} - {% assign hub_app="notebook" %} -{% endif %} - -{% capture interact_url_jupyterhub %}hub/user-redirect/git-pull?repo={{ site.binder_repo_base }}/{{ site.binder_repo_org }}/{{ site.binder_repo_name }}&branch={{ site.binder_repo_branch }}&subPath={{ page.interact_link | url_encode }}&app={{ hub_app }}{% endcapture %} -{% capture interact_icon_jupyterhub %}{{ site.images_url | relative_url }}/logo_jupyterhub.svg{% endcapture %} - - -{% endif %} diff --git a/_includes/buttons/nbinteract.html b/_includes/buttons/nbinteract.html deleted file mode 100755 index eaf6e83..0000000 --- a/_includes/buttons/nbinteract.html +++ /dev/null @@ -1,3 +0,0 @@ -{% if site.use_show_widgets_button and page.has_widgets -%} - -{% endif %} \ No newline at end of file diff --git a/_includes/buttons/thebelab.html b/_includes/buttons/thebelab.html deleted file mode 100755 index 44a8322..0000000 --- a/_includes/buttons/thebelab.html +++ /dev/null @@ -1,3 +0,0 @@ -{% if site.use_thebelab_button -%} - -{% endif %} \ No newline at end of file diff --git a/_includes/css_entry.scss b/_includes/css_entry.scss deleted file mode 100755 index f693426..0000000 --- a/_includes/css_entry.scss +++ /dev/null @@ -1,18 +0,0 @@ -@import 'inuitcss/settings/settings.core'; -@import 'settings/settings.global.scss'; - -@import 'inuitcss/tools/tools.font-size'; -@import 'inuitcss/tools/tools.clearfix'; -@import 'inuitcss/tools/tools.hidden'; -@import 'inuitcss/tools/tools.mq'; - -@import 'inuitcss/elements/elements.page'; -@import 'inuitcss/elements/elements.headings'; -@import 'inuitcss/elements/elements.images'; -@import 'inuitcss/elements/elements.tables'; -@import 'elements/elements.typography'; -@import 'elements/elements.syntax-highlighting'; -@import 'elements/elements.tables'; -@import 'elements/elements.links'; - -@import 'components/components.textbook__page'; diff --git a/_includes/fb_tags.html b/_includes/fb_tags.html deleted file mode 100755 index 1ff5bc3..0000000 --- a/_includes/fb_tags.html +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/_includes/footer.html b/_includes/footer.html deleted file mode 100755 index a42f4ea..0000000 --- a/_includes/footer.html +++ /dev/null @@ -1,3 +0,0 @@ -
- -
diff --git a/_includes/google_analytics.html b/_includes/google_analytics.html deleted file mode 100755 index 23b6bd1..0000000 --- a/_includes/google_analytics.html +++ /dev/null @@ -1,11 +0,0 @@ -{% if site.google_analytics.mytrackingcode %} - - - -{% endif %} diff --git a/_includes/head.html b/_includes/head.html deleted file mode 100755 index e4b63f4..0000000 --- a/_includes/head.html +++ /dev/null @@ -1,89 +0,0 @@ - - - - - - {% if page.title %}{{ page.title | escape }}{% else %}{{ site.title | escape }}{% endif %} - - - - - - {% include fb_tags.html %} - - - - - - - - - - - - - - - {% include mathjax.html %} - - - - - - - - - - - - - - - - - - - - - {% include js/nbinteract.html %} - - - {% include js/thebelab.html %} - - - - - - - {% include google_analytics.html %} - - - - - - - - - - - - - {% include js/interact-update.html %} - - - - - - - - - - - - - {% include js/print.html %} - diff --git a/_includes/js/interact-update.html b/_includes/js/interact-update.html deleted file mode 100755 index e93c5ca..0000000 --- a/_includes/js/interact-update.html +++ /dev/null @@ -1,142 +0,0 @@ -{% if site.use_jupyterhub_button or site.use_binder_button %} - -{% endif %} \ No newline at end of file diff --git a/_includes/js/nbinteract.html b/_includes/js/nbinteract.html deleted file mode 100755 index 97772c6..0000000 --- a/_includes/js/nbinteract.html +++ /dev/null @@ -1,33 +0,0 @@ -{% if site.use_show_widgets_button and page.has_widgets %} - - - - -{% endif %} \ No newline at end of file diff --git a/_includes/js/print.html b/_includes/js/print.html deleted file mode 100755 index 9cda3ac..0000000 --- a/_includes/js/print.html +++ /dev/null @@ -1,32 +0,0 @@ - - - diff --git a/_includes/js/thebelab-cell-button.html b/_includes/js/thebelab-cell-button.html deleted file mode 100755 index 3b9da83..0000000 --- a/_includes/js/thebelab-cell-button.html +++ /dev/null @@ -1,27 +0,0 @@ -{% if site.use_thebelab_button -%} - -{% endif %} diff --git a/_includes/js/thebelab-page-config.html b/_includes/js/thebelab-page-config.html deleted file mode 100755 index 94478c7..0000000 --- a/_includes/js/thebelab-page-config.html +++ /dev/null @@ -1,32 +0,0 @@ - \ No newline at end of file diff --git a/_includes/js/thebelab.html b/_includes/js/thebelab.html deleted file mode 100755 index 97b970c..0000000 --- a/_includes/js/thebelab.html +++ /dev/null @@ -1,95 +0,0 @@ - -{% if site.use_thebelab_button %} - - -{% include js/thebelab-cell-button.html %} - - -{% endif %} diff --git a/_includes/mathjax.html b/_includes/mathjax.html deleted file mode 100755 index f25affe..0000000 --- a/_includes/mathjax.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - diff --git a/_includes/metadata.json b/_includes/metadata.json deleted file mode 100755 index 089680f..0000000 --- a/_includes/metadata.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "@context": "http://schema.org", - "@type": "NewsArticle", - "mainEntityOfPage": "{{ page.url | replace:'index.html','' | prepend: site.baseurl | prepend: site.url }}", - "headline": "{% if page.title %}{{ page.title | escape }}{% else %}{{ site.title | escape }}{% endif %}", - "datePublished": "{% if page.date %}{{ page.date | date_to_xmlschema }}{% else %}{{ site.time | date_to_xmlschema }}{% endif %}", - "dateModified": "{% if page.date %}{{ page.date | date_to_xmlschema }}{% else %}{{ site.time | date_to_xmlschema }}{% endif %}", - "description": "{{ page.content | strip_html | strip_newlines | truncate: 160 }}", - "author": { - "@type": "Person", - "name": "{{ site.author }}" - }, - "publisher": { - "@type": "Organization", - "name": "Data 100 at UC Berkeley", - "logo": { - "@type": "ImageObject", - "url": "{{ site.logo | prepend: site.baseurl | prepend: site.url }}", - "width": 60, - "height": 60 - } - }, - "image": { - "@type": "ImageObject", - "url": "{{ site.logo | prepend: site.baseurl | prepend: site.url }}", - "height": 60, - "width": 60 - } -} diff --git a/_includes/page-nav.html b/_includes/page-nav.html deleted file mode 100755 index 58e860e..0000000 --- a/_includes/page-nav.html +++ /dev/null @@ -1,37 +0,0 @@ -{% comment %} -Only the URLs from the TOC are used here. The title for -prev/next is pulled from the respective page's metadata. -We loop through the "build" collection to determine the -page title based on the *current* page's next/prev URL. -{% endcomment %} - diff --git a/_includes/search/lunr/lunr-en.js b/_includes/search/lunr/lunr-en.js deleted file mode 100755 index b21ace9..0000000 --- a/_includes/search/lunr/lunr-en.js +++ /dev/null @@ -1,84 +0,0 @@ -var initQuery = function() { - // See if we have a search box - var searchInput = document.querySelector('input#lunr_search'); - if (searchInput === null) { - return; - } - - // Function to parse our lunr cache - var idx = lunr(function () { - this.field('title') - this.field('excerpt') - this.field('categories') - this.field('tags') - this.ref('id') - - this.pipeline.remove(lunr.trimmer) - - for (var item in store) { - this.add({ - title: store[item].title, - excerpt: store[item].excerpt, - categories: store[item].categories, - tags: store[item].tags, - id: item - }) - } - }); - - // Run search upon keyup - searchInput.addEventListener('keyup', function () { - var resultdiv = document.querySelector('#results'); - var query = document.querySelector("input#lunr_search").value.toLowerCase(); - var result = - idx.query(function (q) { - query.split(lunr.tokenizer.separator).forEach(function (term) { - q.term(term, { boost: 100 }) - if(query.lastIndexOf(" ") != query.length-1){ - q.term(term, { usePipeline: false, wildcard: lunr.Query.wildcard.TRAILING, boost: 10 }) - } - if (term != ""){ - q.term(term, { usePipeline: false, editDistance: 1, boost: 1 }) - } - }) - }); - - // Empty the results div - while (resultdiv.firstChild) { - resultdiv.removeChild(resultdiv.firstChild); - } - - resultdiv.insertAdjacentHTML('afterbegin', '

'+result.length+' Result(s) found

'); - for (var item in result) { - var ref = result[item].ref; - if(store[ref].teaser){ - var searchitem = - '
'+ - '
'+ - '

'+ - ''+store[ref].title+''+ - '

'+ - '
'+ - ''+ - '
'+ - '

'+store[ref].excerpt.split(" ").splice(0,20).join(" ")+'...

'+ - '
'+ - '
'; - } - else{ - var searchitem = - '
'+ - '
'+ - '

'+ - ''+store[ref].title+''+ - '

'+ - '

'+store[ref].excerpt.split(" ").splice(0,20).join(" ")+'...

'+ - '
'+ - '
'; - } - resultdiv.insertAdjacentHTML('beforeend', searchitem); - } - }); -}; - -initFunction(initQuery); diff --git a/_includes/search/lunr/lunr-store.js b/_includes/search/lunr/lunr-store.js deleted file mode 100755 index ffa41a0..0000000 --- a/_includes/search/lunr/lunr-store.js +++ /dev/null @@ -1,28 +0,0 @@ -var store = [ - {%- for c in site.collections -%} - {%- if forloop.last -%} - {%- assign l = true -%} - {%- endif -%} - {%- assign docs = c.docs | where_exp:'doc','doc.search != false' -%} - {%- for doc in docs -%} - {%- if doc.header.teaser -%} - {%- capture teaser -%}{{ doc.header.teaser }}{%- endcapture -%} - {%- else -%} - {%- assign teaser = site.teaser -%} - {%- endif -%} - { - "title": {{ doc.title | jsonify }}, - {% assign truncateWords=site.search_max_words_in_content %} - "excerpt": {{ doc.search | jsonify }}, - "categories": {{ doc.categories | jsonify }}, - "tags": {{ doc.tags | jsonify }}, - "url": {{ doc.url | absolute_url | jsonify }}, - "teaser": - {%- if teaser contains "://" -%} - {{ teaser | jsonify }} - {%- else -%} - {{ teaser | absolute_url | jsonify }} - {%- endif -%} - }{%- unless forloop.last and l -%},{%- endunless -%} - {%- endfor -%} - {%- endfor -%}] \ No newline at end of file diff --git a/_includes/sidebar.html b/_includes/sidebar.html deleted file mode 100755 index 192aa69..0000000 --- a/_includes/sidebar.html +++ /dev/null @@ -1,157 +0,0 @@ -{% comment %} -Partial for the textbook sidebar. Renders each chapter and its sections from -_data/toc.yml . - -Much of the logic here is to add active classes to the currently active -section. The currently active section / chapter should be highlighted in the -sidebar. - -If a chapter or any of its sections are the current page, we should display the -chapter's sections. Otherwise, we hide the sections to keep the sidebar short. - -We also prefix the sidebar entries with the chapter/section number. We assume -a 1-level nesting; we will label 1.2, but not 1.2.1. -{% endcomment %} - -{% assign chapter_num = 1 %} - - diff --git a/_includes/topbar.html b/_includes/topbar.html deleted file mode 100755 index 3a26729..0000000 --- a/_includes/topbar.html +++ /dev/null @@ -1,23 +0,0 @@ -
- -
- - {% include buttons.html %} -
- - - - Search - -
diff --git a/_layouts/default.html b/_layouts/default.html deleted file mode 100755 index 5a49bb4..0000000 --- a/_layouts/default.html +++ /dev/null @@ -1,27 +0,0 @@ - - - {% include head.html %} - - - {% include js/thebelab-page-config.html %} - - -
- {% include sidebar.html %} - {% if page.search_page != true %} - {% endif %} - {% include topbar.html %} -
-
- {{ content }} -
- - -
- - - - diff --git a/_sass/components/_components.book__layout.scss b/_sass/components/_components.book__layout.scss deleted file mode 100755 index 7caa4a4..0000000 --- a/_sass/components/_components.book__layout.scss +++ /dev/null @@ -1,151 +0,0 @@ -/** - * The website contains two main components: the sidebar and the textbook page. - * This file specifies the layout and includes classes to show/hide the sidebar - * on small screens. - * - * The actual styling for the sidebar and page are located in their respective - * component SCSS files. This file manages the layout and width only. - * - * By default, the sidebar is not visible. - * - * [1]: The entire page is positioned relative so that when the page overflows - * (e.g. sidebar open on small screens) the user can't scroll left/right. - * [2]: The sidebar and the textbook page are positioned absolute so that we - * can use translate() on the textbook page to reveal the sidebar. - * [3]: Setting the background color hides the sidebar when it's behind the - * page (otherwise the page is transparent). - * - * When the sidebar is visible: - * - * [4]: Shift the textbook page over to the left. On small screens, the page - * will overflow since the sidebar takes up most of the screen. - * [5]: On larger screens, the page and sidebar have enough room to read them - * simultaneously, so make sure that the page doesn't overflow. - */ - -$left-sidebar-width: 300px; -$page-max-width: 880px; -$right-sidebar-width: 220px; -$topbar-height: 60px; - -.c-textbook { - /* [1] */ - position: relative; - height: 100vh; - overflow: hidden; - margin: 0 0 0 auto; -} - -.c-topbar { - background-color: $book-background-color; - position: fixed; - top: 0; - height: $topbar-height; - width: 100%; - left: 0; - padding: $spacing-unit-small $spacing-unit-small 0 $spacing-unit-med * 2; - z-index: 1; - transition: top 250ms, transform 250ms ease; // For animations -} - -@include mq($until: tablet) { - .c-topbar.hidetop { - // At desktop, we stop hiding the navbar - top: -250px; - } -} - -.c-textbook__sidebar, -.c-textbook__page { - /* [2] */ - height: 100vh; - overflow: auto; - position: fixed; - background-color: $book-background-color; /* [3] */ -} - -.c-textbook__sidebar { - width: $left-sidebar-width; - top: 0; - left: 0; -} - -.c-textbook__page { - - width: $textbook-page-width; - transition: transform 250ms ease; - left: 0; - padding: 0 $spacing-unit $spacing-unit-small $spacing-unit-small * 3; - overflow-x: visible; - - &:focus { - /* [2] */ - outline: none; - } -} - -.sidebar__right { - // By default we hide the sidebar - display: none; - - // Spacing for the sidebar - width: $right-sidebar-width - $spacing-unit-small; // To account for the small margin on the right - position: relative; - float: right; - z-index: 1; // Keep sidebar under page content - - @include mq($from: tablet) { - // Show right TOC at laptop size - display: block; - } -} - -.js-show-sidebar { - .c-textbook__page, .c-topbar { - /* [4] */ - transform: translate($left-sidebar-width, 0); - - @include mq($from: tablet) { - /* [5] */ - width: calc(100% - #{$left-sidebar-width}); - } - } -} - -.c-textbook__content { - clear: both; - padding-top: $topbar-height * 1.5; - width: 95%; -} - -.c-textbook__content, .c-textbook__footer { - max-width: $page-max-width; -} - -.c-page__nav { - display: flex; - justify-content: space-between; - align-items: center; - padding-top: 30px; -} - -// Make sure that the bottom content has the same width as non-sidebar content -.footer, .c-page__nav { - @include mq($from: laptop) { - width: $textbook-page-with-sidebar-width; - } -} - -// Scrollbar width -::-webkit-scrollbar { - width: 5px; - background: #f1f1f1; -} - -::-webkit-scrollbar-thumb { - background: #c1c1c1; -} - -main, nav { - scrollbar-width: thin; -} \ No newline at end of file diff --git a/_sass/components/_components.book__topbar.scss b/_sass/components/_components.book__topbar.scss deleted file mode 100755 index d9e0ca5..0000000 --- a/_sass/components/_components.book__topbar.scss +++ /dev/null @@ -1,67 +0,0 @@ -.c-topbar__label { - @include inuit-font-size(12px); - display: inline-block; - margin-left: $spacing-unit-tiny; - vertical-align: middle; - text-transform: uppercase; -} - -.c-topbar { - .hamburger, .buttons { - float: left; - } - - #js-sidebar-toggle { - margin-right: 5px; - padding-top: 4px; - } - - span.hamburger-box { - width: 40px; - height: 30px; - padding-left: 10px; - } - - .c-topbar__buttons { - @include mq($from: tablet) { - width: calc(100% - #{$right-sidebar-width} - 20px) - } - } - - .topbar-right-button { - display: block; - float: right; - padding: 0 1rem; - - img { - width: 20px; - margin-top: 4px; - } - } -} - -// Download buttons - -.download-buttons { - display: none; - position: absolute; - - button { - min-width: 100px !important; - border: 1px white solid !important; - border-radius: 0 !important; - } -} - -.download-buttons-dropdown { - position: relative; - display: inline-block; - - &:hover div.download-buttons { - display: block; - } - - img { - height: 18px; - } -} diff --git a/_sass/components/_components.interact-button.scss b/_sass/components/_components.interact-button.scss deleted file mode 100755 index c552fa5..0000000 --- a/_sass/components/_components.interact-button.scss +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Stylings for Interact and Show Widget buttons. - * - * [1]: We abuse CSS selector specificity here since the buttons at the top of - * the notebook might have both .interact-button and .js=nbinteract-widget. - * [2]: We want the top buttons to be large. - * [3]: However, a .js=nbinteract-widget appearing alone midway through the - * notebook should be small. - * - */ - -$color-interact-button: #5a5a5a !default; - -%interact-button { - @include inuit-font-size(14px); - background-color: $color-interact-button; - border-radius: 3px; - border: none; - color: white; - cursor: pointer; - display: inline-block; - font-weight: 700; - /* [2] */ - padding: $spacing-unit-tiny $spacing-unit-med; - text-decoration: none; - - &:hover, - &:focus { - text-decoration: none; - } -} - -.interact-button-logo { - height: 1.35em; - padding-right: 10px; - margin-left: -5px; -} - -.buttons { - margin-bottom: $spacing-unit; - - /* [1] */ - .interact-button { - @extend %interact-button; - } -} - -.js-nbinteract-widget { - @extend %interact-button; - - /* [3] */ - padding: $spacing-unit-tiny $spacing-unit; - margin-bottom: $spacing-unit-small; -} - -// If the interact button link is changed with a REST param -div.interact-context { - display: inline; - padding-left: 1em; -} \ No newline at end of file diff --git a/_sass/components/_components.page__footer.scss b/_sass/components/_components.page__footer.scss deleted file mode 100755 index 9a4d5c4..0000000 --- a/_sass/components/_components.page__footer.scss +++ /dev/null @@ -1,7 +0,0 @@ -.footer { - text-align: center; - font-size: 14px; - padding: 20px; - opacity: 0.7; - margin-bottom: 0px; -} diff --git a/_sass/components/_components.page__nav.scss b/_sass/components/_components.page__nav.scss deleted file mode 100755 index 69db85e..0000000 --- a/_sass/components/_components.page__nav.scss +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Styling for the Next Page / Previous Page links at the bottom of textbook - * pages. - */ - -$color-nav-links: rgba(0, 140, 255, 0.7); - -.c-page__nav__prev, -.c-page__nav__next { - flex: 1; - color: $color-nav-links; - border: 1px solid $color-nav-links; - border-radius: 3px; - padding: $spacing-unit-small 0; -} - -.c-page__nav__next { - text-align: right; -} diff --git a/_sass/components/_components.page__onthispage.scss b/_sass/components/_components.page__onthispage.scss deleted file mode 100755 index 548ee2d..0000000 --- a/_sass/components/_components.page__onthispage.scss +++ /dev/null @@ -1,100 +0,0 @@ -/** - * Styling for the onthispage elements. - * - * [1]: The sidebar is implemented as ul and li elements so we need to remove - * the bullets and margins. Also make chapter fonts a bit bigger. - * [2]: The entries are tags so we need to remove the default styling. - * [3]: The sidebar divider is just an empty element with a border. - * [4]: The current section needs a higher specificity to override the :hover - * selectors used previously. - * [5]: The logo displayed above the sidebar - * [6]: The footer at the bottom of the sidebar - */ -$color-sidebar-bg: rgba(255, 255, 255, 0) !default; -$color-sidebar-entry: #364149 !default; -$color-sidebar-entry--active: $color-links !default; -$color-sidebar-divider: #bbb !default; - -.c-textbook__sidebar { - background-color: $color-sidebar-bg; - padding: $spacing-unit-small; - - @include inuit-font-size(14px); - border-right: 1px solid rgba(0, 0, 0, 0.07); - opacity: 0.6; - -webkit-transition: opacity 0.2s ease-in-out; - transition: opacity 0.2s ease-in-out; - - &:hover { - opacity: 1; - } -} - -/* [1] */ -.c-sidebar__chapters { - list-style: none; - margin-left: 0; - margin-bottom: 0; -} - -li.c-sidebar__chapter > a { - font-size: 1.2em; -} - -/* [1] */ -.c-sidebar__sections, .c-sidebar__subsections { - list-style: none; - margin-bottom: 0; -} - -.c-sidebar__sections { - margin-left: $spacing-unit-small; -} - -.c-sidebar__subsections { - margin-left: 20px; -} - -/* [2] */ -.c-sidebar__entry { - display: block; - - padding: $spacing-unit-tiny; - - color: $color-sidebar-entry; - text-decoration: none; - - &:hover { - text-decoration: underline; - } - - &:visited { - color: $color-sidebar-entry; - } -} - -/* [4] */ -.c-sidebar__entry--active.c-sidebar__entry--active { - color: $color-sidebar-entry--active; -} - -/* [3] */ -.c-sidebar__divider { - border-top: 1px solid $color-sidebar-divider; - margin: $spacing-unit-tiny; -} - -/* [5] */ -img.textbook_logo { - margin-top: 20px; - max-height: 100px; - margin: 0px auto 20px auto; - display: block; -} - -/* [6] */ -p.sidebar_footer { - text-align: center; - padding: 10px 20px 0px 0px; - font-size: .9em; -} \ No newline at end of file diff --git a/_sass/components/_components.search.scss b/_sass/components/_components.search.scss deleted file mode 100755 index 0f3ae89..0000000 --- a/_sass/components/_components.search.scss +++ /dev/null @@ -1,97 +0,0 @@ -/* ========================================================================== - SEARCH - ========================================================================== */ - // Taken from https://github.com/mmistakes/minimal-mistakes - // Variables - $large: 1024px !default; - $x-large: 1280px !default; - $type-size-1: 2.441em !default; - $type-size-2: 1.953em !default; - $type-size-3: 1.563em !default; - $type-size-6: 0.75em !default; - $intro-transition: intro 0.3s both !default; - - // Rules - .layout--search { - .archive__item-teaser { - margin-bottom: 0.25em; - } - } - - .search__toggle { - margin-left: 1rem; - margin-right: 1rem; - border: 0; - outline: none; - color: #393e46; - background-color: transparent; - cursor: pointer; - -webkit-transition: 0.2s; - transition: 0.2s; - - &:hover { - color: #000; - } - } - - .search-icon { - width: 100%; - height: 100%; - } - - .search-content { - //display: none; - //visibility: hidden; - padding-top: 1em; - padding-bottom: 1em; - - &__inner-wrap { - width: 100%; - margin-left: auto; - margin-right: auto; - padding-left: 1em; - padding-right: 1em; - -webkit-animation: $intro-transition; - animation: $intro-transition; - -webkit-animation-delay: 0.15s; - animation-delay: 0.15s; - - .search-input { - display: block; - margin-bottom: 0; - padding: 0; - border: none; - outline: none; - box-shadow: none; - background-color: transparent; - font-size: $type-size-3; - } - } - - &.is--visible { - display: block; - visibility: visible; - - &::after { - content: ""; - display: block; - } - } - - .results__found { - margin-top: 0.5em; - font-size: $type-size-6; - } - - .archive__item { - margin-bottom: 2em; - } - - .archive__item-title { - margin-top: 0; - } - - .archive__item-excerpt { - margin-bottom: 0; - } - } \ No newline at end of file diff --git a/_sass/components/_components.thebelab.scss b/_sass/components/_components.thebelab.scss deleted file mode 100755 index 2bc6859..0000000 --- a/_sass/components/_components.thebelab.scss +++ /dev/null @@ -1,33 +0,0 @@ - -.thebelab-cell { - // To ensure that thebelab cells are always the top of the Z-stack - position: relative; - z-index: 999; -} - -.thebelab-button { - z-index: 999; - display: inline-block; - padding: 0.35em 1.2em; - margin: 0px 1px; - border-radius: 0.12em; - box-sizing: border-box; - text-decoration: none; - font-family: 'Roboto', sans-serif; - font-weight: 300; - text-align: center; - transition: all 0.2s; - background-color: #dddddd; - border: 0.05em solid white; - color: #000000; -} - -.thebelab-button:hover{ - border: 0.05em solid black; - background-color: #fcfcfc; -} - - -div.jp-OutputArea-output { - padding: 5px; -} diff --git a/_sass/hamburgers/_base.scss b/_sass/hamburgers/_base.scss deleted file mode 100755 index 15f4b2d..0000000 --- a/_sass/hamburgers/_base.scss +++ /dev/null @@ -1,69 +0,0 @@ -// Hamburger -// ================================================== -.hamburger { - padding: $hamburger-padding-y $hamburger-padding-x; - display: inline-block; - cursor: pointer; - - transition-property: opacity, filter; - transition-duration: $hamburger-hover-transition-duration; - transition-timing-function: $hamburger-hover-transition-timing-function; - - // Normalize (