# Miscellaneous Modules
## SymPy
**SymPy** is a symbolic mathematics module for Python. 


```
from __future__ import print_function, division
from sympy import *
x, y, z, t = symbols('x y z t')
k, m, n = symbols('k m n', integer=True)
f, g, h = symbols('f g h', cls=Function)
init_printing()

a = Integral(cos(x), x)
Eq(a, a.doit())
```


```
b = Integral(sqrt(1/x), x)
Eq(b, b.doit())
```


```
s = "x**2 + 3*x - 1/2"
c = sympify(s)
d = diff(c)
pretty_print(d)
print(d.subs(x, 2))
```

    2⋅x + 3
    7



```
print(integrate(exp(-x), (x, 0, oo)))
```

    1



```
integrate(exp(-x**2 - y**2), (x, -oo, oo), (y, -oo, oo))
```

## Vectorize Calculations
NumPy functions are optimized to work with arrays and are much faster than performing the computations in loops. This can be demonstrated by calculating the $\sin$ of an array of numbers using any **math** function inside a loop and using the corresponding NumPy function.


```
import math
import numpy as np

def f1(x):
    y = np.zeros(x.shape, dtype=float)
    for i in range(len(x)):
        y[i] = math.sin(x[i])
    return x

def f2(x):
    return np.sin(x)

x = np.linspace(0, 10, 1001)
%timeit f1(x)
%timeit f2(x)
```

    1000 loops, best of 3: 427 µs per loop
    10000 loops, best of 3: 24.8 µs per loop


## Numba

Numba provides a Just In Time compiler to generate optimized machine code to speed up computations in Python. It uses LLVM compiler infrastructure.


```
import numpy as np
from numba import f8, jit

def sum1d(x):
    s = 0.0
    for i in range(x.shape[0]):
        s += x[i]
    return s

@jit(f8(f8[:]))
def fast_sum1d(x):
    s = 0.0
    for i in range(x.shape[0]):
        s += x[i]
    return s

x = np.linspace(0, 100, 1001)

%timeit sum1d(x)
%timeit fast_sum1d(x)
```

    1000 loops, best of 3: 196 µs per loop
    1000000 loops, best of 3: 1.22 µs per loop


Let us compute the approximate value of $\pi$ using the following sum:

$$\pi \approx \sqrt{6 \sum_{k=1}^{n+1} \frac{1}{k^2}}$$


```
def approx_pi(n=10000):
    s = 0
    for k in range(1, n+1):
        s += 1.0 / k**2
    return (6 * s) ** 0.5

%timeit approx_pi(1000)
%timeit approx_pi(10000)

print(approx_pi(1000))
print(approx_pi(10000))
```

    10000 loops, best of 3: 174 µs per loop
    1000 loops, best of 3: 1.8 ms per loop
    3.14063805621
    3.14149716395



```
from numba.decorators import autojit

@autojit
def fast_approx_pi(n):
    s = 0
    for k in range(1, n+1):
        s += 1.0 / k**2
    return (6 * s) ** 0.5

n = 10000
%timeit approx_pi(n)
%timeit fast_approx_pi(n)
```

    100 loops, best of 3: 1.83 ms per loop
    10000 loops, best of 3: 44.8 µs per loop


## Other Modules

1. **Data frames, data munging:** pandas
2. **Machine learning:** scikit-learn
3. **Statistical modelling:** statsmodels
4. **Image processing:** scikits-image

# Image Processing using scikit-image
scikit-image is an image proessing module for SciPy.While SciPy has some image processing functions, scikit-image greatly enhances image processing capabilities of Python.


```
import matplotlib.pyplot as plt
from scipy import ndimage
from skimage import data, io, filter
%matplotlib inline


```


```
image = data.coins() # or any NumPy array!
plt.subplot(211)
io.imshow(image)
plt.subplot(212)
edges = filter.sobel(image)
io.imshow(edges)
plt.show()
```


```

```

e7089de1707dc9fec29389521d0593da894bf7d7
ipynb
Jupyter Notebook
gnunify2015/gnunify06_Miscellaneous.ipynb
satish-annigeri/Notebooks
92a7dc1d4cf4aebf73bba159d735a2e912fc88bb
CC0-1.0
gnunify2015/gnunify06_Miscellaneous.ipynb
satish-annigeri/Notebooks
92a7dc1d4cf4aebf73bba159d735a2e912fc88bb
CC0-1.0
gnunify2015/gnunify06_Miscellaneous.ipynb
satish-annigeri/Notebooks
92a7dc1d4cf4aebf73bba159d735a2e912fc88bb
CC0-1.0
Qwen/Qwen-72B
1. YES
2. YES