<jupyter_start><jupyter_text>Basics [F2PY]---- Author: <NAME>- GitHub: [github.com/diegoinacio](https://github.com/diegoinacio)- Notebook: [basics_F2PY.ipynb](https://github.com/diegoinacio/computer-vision-notebooks/blob/master/High-Performance-Computing/basics_F2PY.ipynb)- Spec: **CPU** i7-9750H 2.6 GHz **GPU** GeForce RTX 2060---Basic functions and operations using [F2PY](https://numpy.org/devdocs/f2py/index.html), *NumPy* and *Python*.<jupyter_code>import numpy as np<jupyter_output><empty_output><jupyter_text>0. Installation---F2PY is a native *Fortran* to *Python* interface generator from [NumPy](https://numpy.org/). Thus, the [Installation](https://numpy.org/devdocs/user/install.html) command for *anaconda* and *pip*:```$ conda install numpy```or```$ pip install numpy```  1. Compilation---A *Fortran* source file can have the name of the module. For example, given the source file `examples_f2py.f90` with a simple function which returns a string in bytes.```fortranfunction hello_f2py() result(output)    character(len=12) :: output    output = "Hello, F2PY!"end function hello_f2py```The following step is the compilation, which is done by running the command:```$ f2py -m examples_f2py -c examples_f2py.f90```<jupyter_code>from examples_f2py import hello_f2py
print(hello_f2py())<jupyter_output>b'Hello, F2PY!'<jupyter_text>2. Performance---The following example, we will try to approximate the value $\large\pi$ with the idea of $\\tan^{-1}1=\frac{\pi}{4}$ using the power series of *arctan*, defined by:$$\large4 \sum_{n=0}^{N}\frac{(-1)^n}{2n+1} \approx \pi$$where $N$ tends to the infinity.<jupyter_code>def pi_py(N):
    pi = 0
    for n in range(N):
        pi += (-1)**n/(2*n + 1)
    return 4*pi

print(pi_py(1000000))<jupyter_output>3.1415916535897743<jupyter_text>In the same *Fortran* source file `examples_f2py.f90`, lets include the function and adapt it to be compiled.```fortranfunction pi_f2py(N_) result(pi)    integer :: N_, n    real    :: pi    pi = 0    do n=0,N_        pi = pi + (-1)**n/real(2*n + 1)    end do    pi = 4*piend function pi_f2py```*p.s.: compile it again by running the command:*```$ f2py -m examples_f2py -c examples_f2py.f90```<jupyter_code>from examples_f2py import pi_f2py
# Time measurement over the situations
print('[Python] pi_py |', end=' ')
%timeit -n 5 -r 5 pi_py(1000000)
print('[F2PY] pi_f2py |', end=' ')
%timeit -n 5 -r 5 pi_f2py(1000000)<jupyter_output>[Python] pi_py | 576 ms ± 3.33 ms per loop (mean ± std. dev. of 5 runs, 5 loops each)
[F2PY] pi_f2py | 1.02 ms ± 11.1 µs per loop (mean ± std. dev. of 5 runs, 5 loops each)<jupyter_text>3. Inline fortran source---Build inline fortran commands and compile with `numpy.f2py`.<jupyter_code>fsource = '''
recursive function factorial(x) result(output)
    integer :: x, output
    if (x <= 1) then
        output = 1
    else
        output = x*factorial(x - 1)
    end if
end function factorial
'''

import numpy.f2py
numpy.f2py.compile(
    fsource, modulename='example_f2py', extension='.f90', verbose=0
)
from example_f2py import factorial
print(factorial(10))<jupyter_output>3628800
{'fraction_non_alphanumeric': 0.1466709552910904, 'fraction_numerical': 0.04889031843036346, 'mean_word_length': 4.613718411552346, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 18, 'https://': 5, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '381150', 'license': 'MIT', 'n_tokens_mistral': 1232, 'n_tokens_neox': 1124, 'n_words': 314, 'path': 'High-Performance-Computing/basics_F2PY.ipynb', 'repo_name': 'romuloallc/computer-vision-notebooks', 'size': '3115'}