<p>
Scientific Computing with Python
</p>

<h3>Contents</h3>
<ul>
<li><a href="#install">Installation</a>
<ul>
<li><a href="#install_spyder">Spyder</a></li>
<li><a href="#install_numpy">NumPy</a></li>
<li><a href="#install_scipy">SciPy</a></li>
<li><a href="#install_matplotlib">Matplotlib</a></li>
</ul>
</li>
<li><a href="#examples">Examples</a>
<ul>
<li><a href="#examples_sine">Sine</a></li>
<li><a href="#examples_curve">Curve fitting</a></li>
</ul>
</li>
</ul>


<h3 id="install">Installation</h3>

<h4 id="install_spyder">Spyder</h4>
<p>
Scientific Python Development Environment
</p>
<pre><code class="language-bash">sudo apt install python3-spyder spyder</code></pre>
<ul>
<li><a href="https://www.spyder-ide.org/" target="_blank">
https://www.spyder-ide.org/</a></li>
</ul>

<h4 id="install_numpy">NumPy</h4>
<p>
Library for numerical linear algebra,<br />
such as the inverse of a matrix, etc.
</p>
<pre><code class="language-bash">sudo apt install python3-numpy</code></pre>
<ul>
<li><a href="https://numpy.org/" target="_blank">
https://numpy.org/</a></li>
</ul>

<h4 id="install_scipy">SciPy</h4>
<p>
Library with fundamental scientific algorithms,<br />
such as the fast Fourier transform (FFT), etc.
</p>
<pre><code class="language-bash">sudo apt install python3-scipy python-scipy-doc</code></pre>
<ul>
<li><a href="https://scipy.org/" target="_blank">
https://scipy.org/</a></li>
</ul>

<h4 id="install_matplotlib">Matplotlib</h4>
<p>
Library for data visualization
</p>
<pre><code class="language-bash">sudo apt install python3-matplotlib</code></pre>
<ul>
<li><a href="https://matplotlib.org/" target="_blank">
https://matplotlib.org/</a></li>
</ul>


<h3 id="examples">Examples</h3>

<h4 id="examples_sine">Sine</h4>
<dl class="file" id="plot_sine.py">
<dt><code class="filename">plot_sine.py</code></dt>
<dd>
<pre class="file"><code class="language-python">#!/usr/bin/env python3

import numpy as np
import matplotlib.pyplot as plt


class Figure:

    def __init__(self):
        self.fig, self.ax = plt.subplots(1, 1)
        self.ax.grid(True)

    def plot_sine(self, start, stop):
        x = np.arange(start, stop, 0.02)
        y = np.sin(x)
        self.ax.plot(x, y)

    def save(self, filename):
        self.fig.savefig(filename)


if __name__ == '__main__':
    figure = Figure()
    figure.plot_sine(0.0, 2.0*np.pi)
    figure.save('sine.svg')
    plt.show()
</code></pre>
</dd>
</dl>
<figure>
<img alt="sine.svg" src="./sine.svg" />
</figure>
<ul>
<li><a href="https://matplotlib.org/stable/api/index.html" target="_blank">
https://matplotlib.org/stable/api/index.html</a></li>
<li><a href="https://en.wikipedia.org/wiki/Sine_and_cosine" target="_blank">
https://en.wikipedia.org/wiki/Sine_and_cosine</a></li>
</ul>

<h4 id="examples_curve">Curve fitting</h4>
<dl class="file" id="fit_curve.py">
<dt><code class="filename">fit_curve.py</code></dt>
<dd>
<pre class="file"><code class="language-python">#!/usr/bin/env python3

import numpy as np
import matplotlib.pyplot as plt
import scipy.optimize


class Figure:

    def __init__(self):
        self.fig, self.ax = plt.subplots(1, 1)
        self.ax.grid(True)
        self.ax.set_xlabel('x')
        self.ax.set_ylabel('f(x)')

    def plot_data(self, data_x, data_y):
        self.ax.plot(data_x, data_y, 'bo', label='data')

    def plot_curve_fit(self, data_x, data_y, func, fmt='r'):
        popt, pcov = scipy.optimize.curve_fit(func.f, data_x, data_y)
        self.ax.plot(data_x, func.f(data_x, *popt), fmt, label=func.string(*popt))
        self.ax.legend()

    def save(self, filename):
        self.fig.savefig(filename)


class LinearFunction:

    def f(x, a, b):
        return a*x + b

    def string(a, b):
        return "f(x) = {:4.2f} x {:+4.2f}".format(a, b)


class QuadraticFunction:

    def f(x, a, b, c):
        return a*x**2 + b*x + c

    def string(a, b, c):
        return "f(x) = {:4.2f} x² {:+4.2f} x {:+4.2f}".format(a, b, c)


if __name__ == '__main__':
    data_x = np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0])
    data_y = np.array([2.5, 6.5, 12.5, 20.5, 30.5, 42.5, 56.5, 72.5])
    figure = Figure()
    figure.plot_data(data_x, data_y)
    figure.plot_curve_fit(data_x, data_y, LinearFunction, 'g')
    figure.plot_curve_fit(data_x, data_y, QuadraticFunction, 'r')
    figure.save('curve_fit.svg')
    plt.show()
</code></pre>
</dd>
</dl>
<figure>
<img alt="curve_fit.svg" src="./curve_fit.svg" />
</figure>
<ul>
<li><a href="https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html" target="_blank">
https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html</a></li>
<li><a href="https://en.wikipedia.org/wiki/Curve_fitting" target="_blank">
https://en.wikipedia.org/wiki/Curve_fitting</a></li>
<li><a href="https://xkcd.com/2048/" target="_blank">
https://xkcd.com/2048/</a></li>
</ul>