Skip to content

Instantly share code, notes, and snippets.

@jfpuget
Created January 27, 2016 18:51
Show Gist options
  • Star 17 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save jfpuget/6f8c82b729677b0173d0 to your computer and use it in GitHub Desktop.
Save jfpuget/6f8c82b729677b0173d0 to your computer and use it in GitHub Desktop.
A Speed Comparison Of C, Julia, Python, Numba, and Cython on LU Factorization
// lu.c
inline int _(int row, int col, int rows){
return row*rows + col;
}
void det_by_lu(double *y, double *x, int N){
int i,j,k;
*y = 1.;
for(k = 0; k < N; ++k){
*y *= x[_(k,k,N)];
for(i = k+1; i < N; ++i){
x[_(i,k,N)] /= x[_(k,k,N)];
}
for(i = k+1; i < N; ++i){
#pragma omp simd
for(j = k+1; j < N; ++j){
x[_(i,j,N)] -= x[_(i,k,N)] * x[_(k,j,N)];
}
}
}
}
function det_by_lu(y, x, N)
y[1] = 1.
for k = 1:N
y[1] *= x[k,k]
for i = k+1:N
x[i,k] /= x[k,k]
end
for j = k+1:N
for i = k+1:N
x[i,j] -= x[i,k] * x[k,j]
end
end
end
end
function run_julia(y,A,B,N)
loops = max(10000000 // (N*N), 1)
print(loops)
for l in 1:loops
B[:,:] = A
det_by_lu(y, B, N)
end
end
y = [0.0]
N=5
A = rand(N,N)
B = zeros(N,N)
@time run_julia(y,A,B,N)
N=5
A = rand(N,N)
B = zeros(N,N)
@time run_julia(y,A,B,N)
N=10
A = rand(N,N)
B = zeros(N,N)
@time run_julia(y,A,B,N)
N=30
A = rand(N,N)
B = zeros(N,N)
@time run_julia(y,A,B,N)
N=100
A = rand(N,N)
B = zeros(N,N)
@time run_julia(y,A,B,N)
N=200
A = rand(N,N)
B = zeros(N,N)
@time run_julia(y,A,B,N)
N=300
A = rand(N,N)
B = zeros(N,N)
@time run_julia(y,A,B,N)
N=400
A = rand(N,N)
B = zeros(N,N)
@time run_julia(y,A,B,N)
N=600
A = rand(N,N)
B = zeros(N,N)
@time run_julia(y,A,B,N)
N=1000
A = rand(N,N)
B = zeros(N,N)
@time run_julia(y,A,B,N)
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# A Speed Comparison Of C, Julia, Python, Numba, and Cython on LU Factorization\n",
"\n",
"## [Jean-François Puget](https://www.ibm.com/developerworks/community/blogs/jfp?lang=en)\n",
"\n",
"The code in this notebook has been used to generate the results discussed in [A Speed Comparison Of C, Julia, Python, Numba, and Cython on LU Factorization](https://www.ibm.com/developerworks/community/blogs/jfp/entry/a_comparison_of_c_julia_python_numba_cython_scipy_and_blas_on_lu_factorization)\n",
"\n",
"\n",
"This study was inspired by Sebastian F. Walter's [Speed comparision Numba vs C vs pure Python at the example of the LU factorization](http://expdesign.iwr.uni-heidelberg.de/people/swalter/blog/python_numba/index.html)\n",
"\n",
"Timingsheavily depend on the machine you use."
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
},
"source": [
"We start with an import of useful packages."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"import numpy as np\n",
"import pandas as pd\n",
"import time\n",
"from numpy.testing import *\n",
"from scipy.linalg import *\n",
"\n",
"import gc\n",
"from matplotlib import pyplot as plt\n",
"%matplotlib inline\n",
"\n",
"from numba import jit, void, double"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Pure Python"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def det_by_lu(y, x):\n",
" y[0] = 1.\n",
"\n",
" N = x.shape[0]\n",
" for k in range(N):\n",
" y[0] *= x[k,k]\n",
" for i in range(k+1, N):\n",
" x[i,k] /= x[k,k]\n",
" for j in range(k+1, N):\n",
" x[i,j] -= x[i,k] * x[k,j]"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def run_python(A,B,y,N):\n",
"\n",
" # check that result is correct\n",
" np.copyto(B,A)\n",
" det_by_lu(y, B)\n",
"\n",
" L = np.tril(B, -1) + np.eye(N)\n",
" U = np.triu(B)\n",
" assert_almost_equal( L.dot(U), A)\n",
" \n",
" gc.disable()\n",
" st = time.time()\n",
" \n",
" loops = 1 + (100000 // (N*N))\n",
" \n",
" for l in range(loops):\n",
" np.copyto(B,A)\n",
" det_by_lu(y, B)\n",
" \n",
" et = time.time()\n",
" gc.enable()\n",
" \n",
" return (et - st)/loops"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Numpy"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def numpy_det_by_lu(y, x):\n",
" y[0] = 1.\n",
"\n",
" N = x.shape[0]\n",
" with np.errstate(invalid='ignore'):\n",
" for k in range(N):\n",
" y[0] *= x[k,k]\n",
" xk = x[k]\n",
" for i in range(k+1, N):\n",
" xi = x[i]\n",
" xi[k] /= xk[k]\n",
" xi[k+1:] -= xi[k] * xk[k+1:]"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def run_numpy(A,B,y,N):\n",
"\n",
" # check that result is correct\n",
" np.copyto(B,A)\n",
" numpy_det_by_lu(y, B)\n",
"\n",
" L = np.tril(B, -1) + np.eye(N)\n",
" U = np.triu(B)\n",
" assert_almost_equal( L.dot(U), A)\n",
" \n",
" gc.disable()\n",
" st = time.time()\n",
" \n",
" loops = 1 + (100000 // (N*N))\n",
" \n",
" for l in range(loops):\n",
" np.copyto(B,A)\n",
" numpy_det_by_lu(y, B)\n",
" \n",
" et = time.time()\n",
" gc.enable()\n",
" \n",
" return (et - st)/loops"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Numba"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"def numba_det_by_lu(y, x):\n",
" y[0] = 1.\n",
"\n",
" N = x.shape[0]\n",
" for k in range(N):\n",
" y[0] *= x[k,k]\n",
" for i in range(k+1, N):\n",
" x[i,k] /= x[k,k]\n",
" for j in range(k+1, N):\n",
" x[i,j] -= x[i,k] * x[k,j]\n",
" \n",
"\n",
"fastdet_by_lu = jit(void(double[:], double[:,:]))(numba_det_by_lu)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def run_numba(A,B,y,N):\n",
"\n",
" # check that result is correct\n",
" np.copyto(B,A)\n",
" fastdet_by_lu(y, B)\n",
"\n",
" L = np.tril(B, -1) + np.eye(N)\n",
" U = np.triu(B)\n",
" assert_almost_equal( L.dot(U), A)\n",
" \n",
" gc.disable()\n",
" st = time.time()\n",
" \n",
" loops = 1 + min(1000000 // (N*N), 20000)\n",
" \n",
" for l in range(loops):\n",
" np.copyto(B,A)\n",
" fastdet_by_lu(y, B)\n",
" \n",
" et = time.time()\n",
" gc.enable()\n",
" \n",
" return (et - st)/loops"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Cython"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"%load_ext cython"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"%%cython\n",
"\n",
"import cython\n",
"\n",
"@cython.boundscheck(False)\n",
"@cython.wraparound(False)\n",
"cpdef cython_det_by_lu(double[:] y, double[:,:] x):\n",
" y[0] = 1.\n",
"\n",
" cdef int N = x.shape[0]\n",
" cdef int i,j,k\n",
" \n",
" for k in range(N):\n",
" y[0] *= x[k,k]\n",
" for i in range(k+1, N):\n",
" x[i,k] /= x[k,k]\n",
" for j in range(k+1, N):\n",
" x[i,j] -= x[i,k] * x[k,j]"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def run_cython(A,B,y,N):\n",
"\n",
" # check that result is correct\n",
" np.copyto(B,A)\n",
" cython_det_by_lu(y, B)\n",
"\n",
" L = np.tril(B, -1) + np.eye(N)\n",
" U = np.triu(B)\n",
" assert_almost_equal( L.dot(U), A)\n",
" \n",
" gc.disable()\n",
" st = time.time()\n",
" \n",
" loops = 1 + min(1000000 // (N*N), 20000)\n",
" for l in range(loops):\n",
" np.copyto(B,A)\n",
" cython_det_by_lu(y, B)\n",
" \n",
" et = time.time()\n",
" gc.enable()\n",
" \n",
" return (et - st)/loops"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
},
"source": [
"### C"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"from cffi import FFI\n",
"ffi = FFI()\n",
"ffi.cdef('void det_by_lu(double *y, double *B, int N);')\n",
"C = ffi.dlopen(r\"C:\\Users\\IBM_ADMIN\\lu.dll\")\n",
"c_det_by_lu = C.det_by_lu"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"def run_c(A,B,y,N):\n",
" # run c code\n",
" #B = numpy.zeros((N,N), order='F')\n",
" #B[:,:] = A\n",
" np.copyto(B,A)\n",
" c_det_by_lu(ffi.cast(\"double *\", y.ctypes.data),\n",
" ffi.cast(\"double *\", B.ctypes.data),\n",
" ffi.cast(\"int\", N))\n",
" \n",
" # check that result is correct\n",
" L = np.tril(B, -1) + np.eye(N)\n",
" U = np.triu(B)\n",
" assert_almost_equal( L.dot(U), A)\n",
" \n",
" gc.disable()\n",
" st = time.time()\n",
" \n",
" loops = 1 + min(1000000 // (N*N), 20000)\n",
" \n",
" for l in range(loops):\n",
" np.copyto(B,A)\n",
" c_det_by_lu(ffi.cast(\"double *\", y.ctypes.data),\n",
" ffi.cast(\"double *\", B.ctypes.data),\n",
" ffi.cast(\"int\", N))\n",
" \n",
" et = time.time()\n",
" gc.enable()\n",
" \n",
" return (et - st)/loops\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Scipy "
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def run_scipy(A,B,y,N):\n",
"\n",
" # check that result is correct\n",
" np.copyto(B,A)\n",
" (P,L,U) = lu(B,overwrite_a=True)\n",
"\n",
" assert_almost_equal( P.dot(L.dot(U)), A)\n",
" \n",
" gc.disable()\n",
" st = time.time()\n",
" \n",
" loops = 1 + min(1000000 // (N*N), 20000)\n",
"\n",
" for l in range(loops):\n",
" np.copyto(B,A)\n",
" lu(B,overwrite_a=True)\n",
" \n",
" et = time.time()\n",
" gc.enable()\n",
" \n",
" return (et - st)/loops"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Lapack"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def run_lapack(A,B,y,N):\n",
"\n",
" # check that result is correct\n",
" \n",
" gc.disable()\n",
" st = time.time()\n",
" \n",
" loops = 1 + min(1000000 // (N*N), 20000)\n",
"\n",
" for l in range(loops):\n",
" np.copyto(B,A)\n",
" lu_factor(B,overwrite_a=True)\n",
" \n",
" et = time.time()\n",
" gc.enable()\n",
" \n",
" return (et - st)/loops"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Timings"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"def timings(n=7, \\\n",
" series=['pure python', 'c', 'numba', 'numpy', \\\n",
" 'cython', 'scipy', 'lapack', 'julia']):\n",
" \n",
" Ns = np.array([5,10,30,100, 200, 300, 400, 600, 1000, 2000, 4000, 8000])\n",
" Fs = [run_python, run_c, run_numba, run_numpy, \\\n",
" run_cython, run_scipy, run_lapack]\n",
" times = pd.DataFrame(np.zeros((n, len(Fs)+1)), index = Ns[:n], columns = series)\n",
" for i,N in enumerate(Ns[:n]):\n",
" print ('N =', N, end=\" \")\n",
" A = np.random.random((N,N))\n",
" B = np.empty(A.shape)\n",
" y = np.zeros(1)\n",
" for j,label in enumerate(series[:-1]):\n",
" if label != '': \n",
" print(j, end=\" \")\n",
" times.loc[N,label] = Fs[j](A,B,y,N)\n",
" print('')\n",
" return times\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Running the code"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"N = 5 0 1 2 3 4 5 6 \n",
"N = 10 0 1 2 3 4 5 6 \n",
"N = 30 0 1 2 3 4 5 6 \n",
"N = 100 0 1 2 3 4 5 6 \n",
"N = 200 0 1 2 3 4 5 6 \n",
"N = 300 0 1 2 3 4 5 6 \n",
"N = 400 0 1 2 3 4 5 6 \n",
"N = 600 0 1 2 3 4 5 6 \n",
"N = 1000 0 1 2 3 4 5 6 \n"
]
}
],
"source": [
"times = timings(9)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Checking results"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>pure python</th>\n",
" <th>c</th>\n",
" <th>numba</th>\n",
" <th>numpy</th>\n",
" <th>cython</th>\n",
" <th>scipy</th>\n",
" <th>lapack</th>\n",
" <th>julia</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>0.000051</td>\n",
" <td>0.000016</td>\n",
" <td>0.000002</td>\n",
" <td>0.000074</td>\n",
" <td>0.000006</td>\n",
" <td>0.000029</td>\n",
" <td>0.000031</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>10</th>\n",
" <td>0.000312</td>\n",
" <td>0.000016</td>\n",
" <td>0.000003</td>\n",
" <td>0.000234</td>\n",
" <td>0.000006</td>\n",
" <td>0.000030</td>\n",
" <td>0.000031</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>30</th>\n",
" <td>0.007800</td>\n",
" <td>0.000028</td>\n",
" <td>0.000014</td>\n",
" <td>0.001950</td>\n",
" <td>0.000014</td>\n",
" <td>0.000070</td>\n",
" <td>0.000056</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>100</th>\n",
" <td>0.289310</td>\n",
" <td>0.000154</td>\n",
" <td>0.000463</td>\n",
" <td>0.029782</td>\n",
" <td>0.000309</td>\n",
" <td>0.000309</td>\n",
" <td>0.000309</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>200</th>\n",
" <td>2.277604</td>\n",
" <td>0.001800</td>\n",
" <td>0.007200</td>\n",
" <td>0.119600</td>\n",
" <td>0.003600</td>\n",
" <td>0.001200</td>\n",
" <td>0.001200</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>300</th>\n",
" <td>7.636214</td>\n",
" <td>0.007800</td>\n",
" <td>0.019500</td>\n",
" <td>0.226200</td>\n",
" <td>0.007800</td>\n",
" <td>0.003900</td>\n",
" <td>0.001300</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>400</th>\n",
" <td>18.267632</td>\n",
" <td>0.017829</td>\n",
" <td>0.051257</td>\n",
" <td>0.514801</td>\n",
" <td>0.020057</td>\n",
" <td>0.008914</td>\n",
" <td>0.002229</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>600</th>\n",
" <td>62.197309</td>\n",
" <td>0.062400</td>\n",
" <td>0.124800</td>\n",
" <td>0.982802</td>\n",
" <td>0.088400</td>\n",
" <td>0.036400</td>\n",
" <td>0.010400</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1000</th>\n",
" <td>290.472510</td>\n",
" <td>0.257401</td>\n",
" <td>0.569401</td>\n",
" <td>3.042005</td>\n",
" <td>0.288600</td>\n",
" <td>0.070200</td>\n",
" <td>0.039000</td>\n",
" <td>0</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" pure python c numba numpy cython scipy lapack \\\n",
"5 0.000051 0.000016 0.000002 0.000074 0.000006 0.000029 0.000031 \n",
"10 0.000312 0.000016 0.000003 0.000234 0.000006 0.000030 0.000031 \n",
"30 0.007800 0.000028 0.000014 0.001950 0.000014 0.000070 0.000056 \n",
"100 0.289310 0.000154 0.000463 0.029782 0.000309 0.000309 0.000309 \n",
"200 2.277604 0.001800 0.007200 0.119600 0.003600 0.001200 0.001200 \n",
"300 7.636214 0.007800 0.019500 0.226200 0.007800 0.003900 0.001300 \n",
"400 18.267632 0.017829 0.051257 0.514801 0.020057 0.008914 0.002229 \n",
"600 62.197309 0.062400 0.124800 0.982802 0.088400 0.036400 0.010400 \n",
"1000 290.472510 0.257401 0.569401 3.042005 0.288600 0.070200 0.039000 \n",
"\n",
" julia \n",
"5 0 \n",
"10 0 \n",
"30 0 \n",
"100 0 \n",
"200 0 \n",
"300 0 \n",
"400 0 \n",
"600 0 \n",
"1000 0 "
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"times"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Adding Julia timings.\n",
"\n",
"Here is the output of the julia code\n",
"```\n",
"400000//1 0.249989 seconds (13 allocations: 576 bytes)\n",
"100000//1 0.127597 seconds (13 allocations: 576 bytes)\n",
"100000//9 0.177901 seconds (13 allocations: 576 bytes)\n",
"1000//1 0.484114 seconds (13 allocations: 576 bytes)\n",
"250//1 0.902625 seconds (13 allocations: 576 bytes)\n",
"1000//9 1.325684 seconds (13 allocations: 576 bytes)\n",
"125//2 1.729400 seconds (13 allocations: 576 bytes)\n",
"250//9 2.650419 seconds (13 allocations: 576 bytes)\n",
"10//1 5.208197 seconds (13 allocations: 576 bytes)```\n",
"\n",
"Massaging data a bit yileds these timings. "
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"julia_times = [6.0914E-07, 1.06071E-06, 9.08208E-06, 0.000226553, 0.001740604, \n",
"0.005823171, 0.013721355, 0.045432148, 0.2642414, 2.728702]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We add these into our timings data frame"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"M = min(len(julia_times),times.shape[0])\n",
"times['julia'] = julia_times[:M]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Checking results again"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>pure python</th>\n",
" <th>c</th>\n",
" <th>numba</th>\n",
" <th>numpy</th>\n",
" <th>cython</th>\n",
" <th>scipy</th>\n",
" <th>lapack</th>\n",
" <th>julia</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>0.000051</td>\n",
" <td>0.000016</td>\n",
" <td>0.000002</td>\n",
" <td>0.000074</td>\n",
" <td>0.000006</td>\n",
" <td>0.000029</td>\n",
" <td>0.000031</td>\n",
" <td>6.091400e-07</td>\n",
" </tr>\n",
" <tr>\n",
" <th>10</th>\n",
" <td>0.000312</td>\n",
" <td>0.000016</td>\n",
" <td>0.000003</td>\n",
" <td>0.000234</td>\n",
" <td>0.000006</td>\n",
" <td>0.000030</td>\n",
" <td>0.000031</td>\n",
" <td>1.060710e-06</td>\n",
" </tr>\n",
" <tr>\n",
" <th>30</th>\n",
" <td>0.007800</td>\n",
" <td>0.000028</td>\n",
" <td>0.000014</td>\n",
" <td>0.001950</td>\n",
" <td>0.000014</td>\n",
" <td>0.000070</td>\n",
" <td>0.000056</td>\n",
" <td>9.082080e-06</td>\n",
" </tr>\n",
" <tr>\n",
" <th>100</th>\n",
" <td>0.289310</td>\n",
" <td>0.000154</td>\n",
" <td>0.000463</td>\n",
" <td>0.029782</td>\n",
" <td>0.000309</td>\n",
" <td>0.000309</td>\n",
" <td>0.000309</td>\n",
" <td>2.265530e-04</td>\n",
" </tr>\n",
" <tr>\n",
" <th>200</th>\n",
" <td>2.277604</td>\n",
" <td>0.001800</td>\n",
" <td>0.007200</td>\n",
" <td>0.119600</td>\n",
" <td>0.003600</td>\n",
" <td>0.001200</td>\n",
" <td>0.001200</td>\n",
" <td>1.740604e-03</td>\n",
" </tr>\n",
" <tr>\n",
" <th>300</th>\n",
" <td>7.636214</td>\n",
" <td>0.007800</td>\n",
" <td>0.019500</td>\n",
" <td>0.226200</td>\n",
" <td>0.007800</td>\n",
" <td>0.003900</td>\n",
" <td>0.001300</td>\n",
" <td>5.823171e-03</td>\n",
" </tr>\n",
" <tr>\n",
" <th>400</th>\n",
" <td>18.267632</td>\n",
" <td>0.017829</td>\n",
" <td>0.051257</td>\n",
" <td>0.514801</td>\n",
" <td>0.020057</td>\n",
" <td>0.008914</td>\n",
" <td>0.002229</td>\n",
" <td>1.372135e-02</td>\n",
" </tr>\n",
" <tr>\n",
" <th>600</th>\n",
" <td>62.197309</td>\n",
" <td>0.062400</td>\n",
" <td>0.124800</td>\n",
" <td>0.982802</td>\n",
" <td>0.088400</td>\n",
" <td>0.036400</td>\n",
" <td>0.010400</td>\n",
" <td>4.543215e-02</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1000</th>\n",
" <td>290.472510</td>\n",
" <td>0.257401</td>\n",
" <td>0.569401</td>\n",
" <td>3.042005</td>\n",
" <td>0.288600</td>\n",
" <td>0.070200</td>\n",
" <td>0.039000</td>\n",
" <td>2.642414e-01</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" pure python c numba numpy cython scipy lapack \\\n",
"5 0.000051 0.000016 0.000002 0.000074 0.000006 0.000029 0.000031 \n",
"10 0.000312 0.000016 0.000003 0.000234 0.000006 0.000030 0.000031 \n",
"30 0.007800 0.000028 0.000014 0.001950 0.000014 0.000070 0.000056 \n",
"100 0.289310 0.000154 0.000463 0.029782 0.000309 0.000309 0.000309 \n",
"200 2.277604 0.001800 0.007200 0.119600 0.003600 0.001200 0.001200 \n",
"300 7.636214 0.007800 0.019500 0.226200 0.007800 0.003900 0.001300 \n",
"400 18.267632 0.017829 0.051257 0.514801 0.020057 0.008914 0.002229 \n",
"600 62.197309 0.062400 0.124800 0.982802 0.088400 0.036400 0.010400 \n",
"1000 290.472510 0.257401 0.569401 3.042005 0.288600 0.070200 0.039000 \n",
"\n",
" julia \n",
"5 6.091400e-07 \n",
"10 1.060710e-06 \n",
"30 9.082080e-06 \n",
"100 2.265530e-04 \n",
"200 1.740604e-03 \n",
"300 5.823171e-03 \n",
"400 1.372135e-02 \n",
"600 4.543215e-02 \n",
"1000 2.642414e-01 "
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"times"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Display"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"def plot_times(times, \n",
" cols = [],\\\n",
" name=\"runtimes.png\"):\n",
" plt.figure(figsize=(7,5))\n",
" if cols == []:\n",
" cols = times.columns\n",
" for i,label in enumerate(cols):\n",
" if label != '':\n",
" plt.loglog(times.index, times[label], label=label)\n",
" plt.xlabel(\"N (matrix size)\")\n",
" plt.ylabel(\"runtime [sec]\")\n",
" plt.grid()\n",
" plt.legend(loc=2)\n",
" plt.savefig(name)\n",
" plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/png": "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\nYII=\n",
"text/plain": [
"<matplotlib.figure.Figure at 0xb17e7b8>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plot_times(times, cols=['pure python', 'c', 'numba'], name='runtimes_1')"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<matplotlib.figure.Figure at 0xbcd9c88>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plot_times(times, cols=['pure python', 'c', 'cython'], name='runtimes_2')"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/png": "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\ns4SLo5mZWeIfULRJfWFtvYMAAAAASUVORK5CYII=\n",
"text/plain": [
"<matplotlib.figure.Figure at 0xd4e4ef0>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plot_times(times, cols=['pure python', 'c', 'numpy'], name='runtimes_3')"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<matplotlib.figure.Figure at 0xbd40828>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plot_times(times, cols=['pure python', 'c', 'scipy', 'lapack'], name='runtimes_4')"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAccAAAFNCAYAAAB116QMAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzs3Xd4U2X7wPHvU5aCYJkORosioKyqDAVHHS9LAQVFQNAq\niogsxYUDihN/LhRQBJECCii4qKCiYBguEBRkI7L3HkVG6f3740lrqbRN2yTnJLk/15Xr5TlJzrn7\n5jF3nnmMiKCUUkqpf0U5HYBSSinlNpoclVJKqSw0OSqllFJZaHJUSimlstDkqJRSSmWhyVEppZTK\nQpOjUkoplYUmR6WUUiqLwk4HkBNjTE2gD1AWmCUiIxwOSSmlVAQwobBDjjHGAGNF5C6nY1FKKRX+\ngtqtaowZbYzZYYxZkuV4c2PMSmPMamPME1meawV8BUwPZqxKKaUiV1BbjsaYq4DDwDgRqes9FgWs\nBm4AtgILgA4isjLLe78SkZuDFqxSSqmIFdQxRxGZZ4yJyXK4IbBGRDYAGGMmAW2AlcaYa4G2QDFg\n2unOaYxxf7+wUkqpoBMRk9/3umG2akVgU6byZu8xRGS2iPQRke4i8m52JxARVz4GDhzo2nPn5/2+\nvseX1+X2muyez+txNzzcXA/yc468vD6/n3M41gO314VQrAc5PVdQbkiOYSs+Pt61587P+319jy+v\ny+012T2f3fH169fnek2nuLke5OcceXl9fj/n3J4PxXoA7q4LoVgP8hpHXgR9tqq3WzVZ/h1zvAJI\nFJHm3vKTgIjIKz6eTwYOHEh8fHxAK55yt4SEBJKSkpwOQzlM64HyeDx4PB4GDRqEFKBb1YnkGItN\njnW85ULAKuyEnG3AfKCjiKzw8XwS7L9BuY/H49EfR0rrgcpgjAmd5GiMmQDEYxf17wAGisgYY0wL\nYAi2m3e0iAzOwzk1OSqllDpFSCXHQMguOcbGxrJhwwYHIlKBEhMTk+2YkrYYFGg9UP8qaHJ09fZx\nvkpMTPzPmOOGDRv8MmNJuYfdKEkppbKXPuZYUGHbcvT+anAgIhUo+pkqpXxV0JajLuVQSimlstDk\nqMKCP7pRVOjTeqD8RZOjUkoplUVYJMfExET9xeiQqlWrMmvWLKfD0BmKCtB6oGzvQWJiYoHPoxNy\nlM/uueceKleuzHPPPZdxrGrVqowePZrrr78+4NfXz1Qp5SudkBPh0tLSnA7BFbTnQIHWA2Xt31/w\nc2hydEDVqlUZPHgwtWrVomzZsnTt2pXjx48DMHbsWK6++upTXh8VFcXff/8N2NZbjx49uOmmmyhZ\nsiQej4fjx4/z6KOPEhMTw3nnnUePHj04duzYaa89duxYrrrqKnr16kV0dDSXXHJJRrfolClTqF+/\n/imvf/PNN7nlllsYNWoUH330Ef/3f/9HqVKlaNOmTcZrfv/9d+rVq0fp0qXp2LFjxt8CMGrUKC66\n6CLKlSvHLbfcwrZt2075u9577z2qV69OmTJl6NmzZwH+X1VKRbq0NBg6FKpX98PJAnX7lGA97J/w\nX9kdd4PY2FipU6eObNmyRfbt2ydNmjSRZ599VkREkpKS5Oqrrz7l9VFRUbJ27VoREUlISJDo6Gj5\n+eefRUTk6NGj0rdvX2nTpo3s379fDh8+LK1bt5annnrqtNdOSkqSwoULy1tvvSWpqany8ccfy9ln\nny379u2TY8eOSdmyZWXlypUZr7/00kvl888/z7h2epyZ/5ZGjRrJ9u3bZd++fXLxxRfLe++9JyIi\nM2fOlHLlyskff/whx48fl169esk111yT8V5jjLRq1UoOHjwoGzdulPLly8u3336b7f9vbv5MlVLO\nWr5cpHFjkSZNRFasyPi+yHduidiWozH+eeRXr169OP/884mOjubpp59m4sSJ2b5WsoyztWnThiuu\nuAKAYsWKMWrUKN58803OPvtsSpQowZNPPpnj+c455xx69+5NoUKFaN++PTVq1GDatGkULVqU9u3b\n8+GHHwKwbNkyNmzYwE033ZTj39KnTx/OOeccoqOjadWqFX/88QcAEyZMoGvXrtSrV48iRYrw8ssv\n8/PPP7Nx48aM9/bv35+SJUtSuXJlrrvuuoz3KqWUL44fhxdegKuvhjvvhDlzoGbNgp83YpOjiH8e\n+VWpUqWMf8fExLB161af31u5cuWMf+/atYsjR45w+eWXU6ZMGcqUKUOLFi3Ys2dPtu+vWLHiKeXM\n17/77ruZMGECAB9++CHt27enSJEiOcZzzjnnZPy7ePHiHD58GICtW7cSExOT8VyJEiUoW7YsW7Zs\nyfW9eaVjTQq0HkSaBQugfn346SdYtAh69IAoP2W1iE2OTtu0aVPGvzds2MD5558P2ARy5MiRjOe2\nb9/+n/dm3mO0XLlyFC9enGXLlrF371727t3L/v37OXDgQLbXzpycADZu3Jhx/UaNGlG0aFHmzp3L\nhAkT6NKly2mv64vzzz//lM3fU1JS2LNnzyk/DJRSKq+OHIFHH4VWreCJJ2DaNKhSxb/XCIvkGIrr\nHIcPH86WLVvYu3cvL730Eh06dACgXr16LFu2jCVLlnDs2DEGDRqUY1IyxnD//ffTt29fdu3aBdjk\nN2PGjGzfs3PnToYOHUpqaiqTJ09m5cqVtGzZMuP5Ll260LNnT4oWLUrjxo0zjp9zzjkZE4N80bFj\nR8aMGZPxtzz11FNcccUVp7R8/UXXtynQehAJZs2CunVh61b480/blZr5K9Jf6xzDJjmG2n8UnTp1\nomnTplSrVo2LLrqIp59+GoCLLrqIAQMGcMMNN1C9evX/zFw9nVdeeYVq1apxxRVXEB0dTdOmTVm9\nenW2r2/UqBFr1qyhXLlyPPvss3z66aeULl064/kuXbqwdOnSU1qNAF27dmXZsmWUKVOGtm3bAjm3\nJm+44Qaef/552rZtS8WKFVm3bh2TJk3KeD7re/WuG0qp7OzfD/ffD3ffDUOGwIQJUL78f18XHx+v\nmwBAaG4CEMyF81mNHTuW0aNHM2fOnGxfc/ToUc455xwWLVrEhRdeGMTocpbTZ6r38VOg9SBcffEF\nPPQQtGkDgwdDqVK5vyes7+dojGkD3ASUBD4Qke8cDikivPPOOzRo0MBViVEpFXm2b4devWDxYpg4\nEa65JnjXdnVyFJEvgS+NMdHAq0BYJEc3dx9WrVoVgC+++MLhSPJGWwsKtB6ECxEYOxYefxy6doVx\n4+DMM4MbQ1C7VY0xo4GbgR0iUjfT8ebAEOwY6GgReSXL+14DPhSR/yyCC8VuVZU/+pkqFf7Wr4du\n3WD3bhg9Gi69NH/nCbW9VccAzTIfMMZEAcO8x2sBHY0xNTM9PxiYfrrEqFS6UJutrAJD60HoOnkS\n3nrLrlu84Qb49df8J0Z/CGq3qojMM8bEZDncEFgjIhsAjDGTgDbASmNML+AGoJQxppqIjAxmvEop\npQJv2TLbfVqsmF3Q75e9UQvIDWOOFYFNmcqbsQkTERkKDM3tBAkJCcTGxgIQHR1NXFyc/6NUrpDe\nMkgfW9KyljOX04+5JR4t51z+7jsPH30E06bF8/zzUL26h61boXr1vJ/P4/GQlJQEkJEPCiLoSzm8\nLcfk9DFHY0w7oJmIdPOWOwMNRaS3j+fTMccIoZ+pUuHj11/hvvsgNhbefRf8vXFWqI05ns4WIPPG\nP5W8x5TyWfovSBXZtB64X0oKPPKIXbP49NMwdar/E6M/OJEcjfeRbgFQzRgTY4wpCnQApublhKG4\nfZxSSkWa77+HOnVg1y5YuhQ6dCjY3Y1Ox+On7eOCvZRjAhAPlAV2AANFZIwxpgWnLuUYnIdzardq\nhNDPVKnQtG8f9OsHM2fCiBHQokXgr1nQblXdPk6FDP1MlQo9n31md7m59VZ4+WUoWTI41w2HMceI\ntHnzZtq1a0eFChUoX748vXv7NP9IZUO71RVoPXCTbdugXTt46in4+GMYNix4idEfwiI5htqYY1pa\nGjfffDNVq1Zl48aNbNmyJeOWVUopFcpEYMwYqFcPLr4Y/vgDrroqeNcPyTHHQMhvt6oZ5J9RYBmY\n9///fvnlF9q0acO2bduIigqL3ydBod2qSrnbunV267e9e+3Wb04uOQ/ru3IEUn6Smr9s2rSJmJgY\nTYxKqbBw8qTtNn3+ebtZ+COPQOEQzy767eyAypUrs3HjRtLS0pwOJWyEUre6ChytB8G3bBk0aWIn\n3vz0k02OoZ4YIUySY6iNOTZs2JDzzjuPJ598kiNHjnDs2DF++uknp8NSSimfHT8Ozz0H8fFwzz3w\nww/u2BNVxxy9QnUpx+bNm+nVqxdz584lKiqKTp06MWTIEKfDcjW3f6ZKRYr58+1G4TExdt2iG3e4\n0XWOIZocVd7pZ6qUs1JSYMAA+OgjePPNwOxw4y+6zlEpdKxJWVoPAmfWLKhbF3bssFu/dezo3sTo\nD2EwbKqUUipQ9u+Hxx6Db7+1d8+46SanIwoO7VZVIUM/U6WC64sv4KGH7B00Bg+GUqWcjsh3us5R\nKaWUX+3YYfdDXbwYJk6Ea65xOqLg0zFHFRZ0rEmB1oOCEoGxY+3Y4oUX2q3fIjExgrYclVJKAevX\nwwMPwM6d8PXXcNllTkfkrLBoOYbaJgDK/+Lj450OQbmA1oO8S0uDoUOhfn27oH/+/NBOjLoJgJdO\nyIkc+pkq5V8rVsB990FUFLz/PtSo4XRE/qPrHENU7dq1mTNnTq6vq1q1KrNmzQLg5Zdfplu3boEO\nLSRpz4ECrQe+OnECXnoJrr4aOnWC2bPDKzH6g6vHHI0xVYGngVIi0t7pePxp6dKleX5P//79AxCJ\nUiqSLFpkt3475xxYuNBuAaf+y9UtRxFZJyL3OR2Hcj8da1Kg9SAn//wD/ftDixbw8MN20o0mxuwF\nNTkaY0YbY3YYY5ZkOd7cGLPSGLPaGPNEMGNySnp36T333MOAAQMyjs+ePZvKlSuf9j2DBg2iS5cu\nGeX27dtz3nnnUbp0aeLj41m+fHnA41ZKhZ558+yNh//6C5YsgbvuCu+t3/wh2C3HMUCzzAeMMVHA\nMO/xWkBHY0zNLO8Lu4/R5FAzfX2uZcuWrF27lp07d3LZZZdx5513+jXGUKJjTQq0HmR16BD07Al3\n3AEvvwyTJ9vuVJW7oCZHEZkH7MtyuCGwRkQ2iMgJYBLQBsAYU8YY8y4Q5/cWpTH+eeSTP2ZdJiQk\nULx4cYoUKcKAAQNYvHgxhw4dKvB5lVKh7+uvoXZtOHLEbhTetq3TEYUWN0zIqQhsylTejE2YiMhe\n4MHcTpCQkEBsbCwA0dHRxMXF5X7VEF8SkJaWxlNPPcWUKVPYvXs3xhiMMezevZuSJUs6HV7ApLcM\n0seWtKzlzOX0Y26Jx4nygQPw6afxzJ0LvXp5qF8fSpd2T3yBKns8HpKSkgAy8kGBiEhQH0AMsCRT\nuR0wMlO5M/B2Hs4np5PdcbeIjY2VmTNnykMPPST9+vXLOD5x4kSpXLnyf14nIpKYmChdunQREZFx\n48bJJZdcIhs2bBARkf3794sxRtauXRvEvyK43P6ZKuWktDSRTz4ROfdckd69RQ4dcjoiZ3m/L/Kd\nq9wwW3ULUCVTuZL3WESIi4tj+vTp7Nu3j+3bt/PWW2/59L7Dhw9TrFgxSpcuTUpKCv37989xrDLc\npf+CVJEtUuvBtm2223TAAPj0U3jrLTjrLKejCm1OJEfDqRNsFgDVjDExxpiiQAdgal5OGMrbx3Xp\n0oW6desSGxtL8+bN6dChwynPZ5fw7rrrLqpUqULFihWpXbs2jRs3Dka4SikXEbE729SrB7Vqwe+/\nQ6R/FXhCcfs4Y8wEIB4oC+wABorIGGNMC2AINlmPFpHBeTinnO5vcPtWYzExMXz00UdcddVVTocS\nMtz+mSoVTGvWQLdukJJiE2Tduk5H5C4F3T5O91Z1wK5du4iNjWXVqlVUqlTJ6XBChps/U6WC5cQJ\neO01eP11eOYZe9/FQoWcjsp9dG9VQqtb9bfffqN69er07t1bE6MfhcrnrwIr3OvBggX27hmzZ8Nv\nv0HfvpoYswrJbtVACMWWo8qfnD7TzNP3VeQK13qQkgLPPgsTJtgWY6dOusNNbrRbVZNjxNDPVEWi\nb7+F7t3tHTTeeAPKlXM6otBQ0OTohk0AlFJKZbF7NzzyCMydCyNGQLNmub9H+U9YjDkqFe5jTco3\n4VAPROCjj+zWb+XL263fNDEGX1i0HBMTE4mPjz9lrCEmJiaiF8WHoxi9v44Kc+vX2y7U7dshORka\nNHA6otDj8Xj88iMpbMcclVIqVJw8CUOHwgsvwKOPQr9+UKSI01GFNh1zVEqpELZkCdx3H5QoAT//\nDBdd5HRECnTMUYWJcBhrUgUXSvXg6FF4+mm48UZ44AGYNUsTo5toy1EppYJs9my79Vu9erbleO65\nTkekstIxR6WUCpL9++Hxx+2NiIcNgzZtnI4ofOn2cUopFQI++8zeOaNIEVi2TBOj22lyVGEhlMaa\nVOC4sR5s2QK33mrHFz/5BIYPh1KlnI5K5UaTo1JKBUBaGrz7LsTF2ccff0CTJk5HpXwVFhNyTrcJ\ngIos+tkrcE89WLEC7r/f7nYzezZcconTEUUO3QTASyfkKKXc4tgxGDzYTrYZNMjudhOl/XOO0Ak5\nSuHOsSYVfE7Wg59+gksvhd9/t48ePTQxhjJXd6saY4oD7wDHgNkiMsHhkJRS6hQHD0L//vDFF/D2\n29C2rd5rMRy4ulvVGNMZ2Cci04wxk0Skw2leo92qSilHfPkl9OwJLVrAK69A6dJOR6TShVS3qjFm\ntDFmhzFmSZbjzY0xK40xq40xT2R6qhKwyfvvk0ELVCmlcrBtG9x+Ozz2GHz4IYwcqYkx3AS7R3wM\ncMqdyYwxUcAw7/FaQEdjTE3v05uwCRJAOypUtnTMUUHg60FaGowaZbd9q1HDbv127bUBvaRySFDH\nHEVknjEm6035GgJrRGQDgDFmEtAGWAl8DgwzxtwEJAczVqWUymzVKrsf6tGjMHMm1KnjdEQqkNww\nIaci/3adAmzGJkxE5Ahwb24nSEhIIDY2FoDo6Gji4uIy1jul/5LUspa1HP7l9GP+PP+JEzB/fjxv\nvgkdO3q45RaoU8cdf6+W/y17PB6SkpIAMvJBQQR9Qo635ZgsInW95XZAMxHp5i13BhqKSG8fz6cT\ncpRSAfHrr/Zei1WqwDvvQEzWfi/lWiE1IScbW4AqmcqVvMeU8ln6L0gV2fxVDw4dgj594JZb4Kmn\n4KuvNDFGGieSo+HUyTULgGrGmBhjTFGgAzA1LydMTEzUL0ellF9Mmwa1a9v1i0uXQseOum4xlHg8\nHhITEwt8nqB2qxpjJgDxQFlgBzBQRMYYY1oAQ7DJerSIDM7DObVbVSlVYDt2QN++MH8+vPce3Hij\n0xGpgihot6qrNwHwhSZHpVRBiEBSEjz5JCQkwMCBULy401GpggqHMccC025VpZ+/grzXg7Vr4X//\nsxuFf/ON3eVGE2NoC8lu1UDQlqOCU6fvq8jlaz04cQLeeANefdXui9qnDxR2w8I25TfararJUSmV\nBwsX2uUZ5cvDiBFwwQVOR6QCQbtVlVLKBykp0K8ftGwJjzwC336riVFlT5OjCgs65qgg+3owY4bd\n7m3HDrs8o0sXXZ6hchYWveyJiYnEx8frmJNS6hS7d8PDD8O8ebYLtVmz3N+jQpvH4/HLj2Udc1RK\nhR0Reyupxx6DTp3guefgrLOcjkoFU0HHHMOi5aiUUunWrYPu3W0XanIyNGjgdEQqFOmYowoLOuao\nUlOhRw8PDRrAddfBggWaGFX+actRKRXyFi+2yzNSU+GXX6BaNacjUk5KW/pngc+hLUcVFnQyVmQ6\nehSeftructO9OyxaFK+JMYJJaiqrenZkT5NLC3wuTY5KqZA0Zw7UqwerVtmWY9euujwjkq1bOo8/\n657D3u+msvybDwt8Pk2OKizomGPkOHAAHnzQ3kpq8GCYMgXOO88+p/Ug8qQcT2Hcyx0ofuU1HGjS\ngMv/3M21V3Yo8Hk1OSqlQsbUqfZeiydPwrJlcOutTkeknCIifPrHRD5qdh4t30gmavIUrh71DUWL\nnumX84fFhBzdBEDpZx/eduyA3r1h0SIYN87ORj0drQeRYcWuFbw09j4eH/47518QR9mVyVC2LKCb\nAGTQTQCUCl8iMHYsPP443Huvvdfimf5pGKgQdPDYQZ6b/Rz7xo9k6DSh2LOJFOr7yGkHm3UTAKXQ\nW1aFo7//hgcegD177L0WL7ss9/doPQhPIsKEPycw4OvHeN9TiqtXlaHwjClQv37ArunaMUdjTFVj\nzPvGmE+cjkUpFTwnT9p7LTZsaJdozJ/vW2JU4Wnx9sVck3QNn33xEkuSinPd2XEU/n1xQBMj5NKt\naox5xIdzpIjIe/4L6T8xfCIi7XN4XrtVlQoTS5bYxfxnnQUjR+pi/ki27599DPhhAJ8s+5hJh1sQ\n/850zEsv2Qriw5qdQN/P8THgLKBkDo9+uQQ42hizwxizJMvx5saYlcaY1caYJ/L7ByilQt/Ro/DM\nM3DjjdCtG8ycqYkxUqVJGqMXjebi4RcTdTiFjYviuW7Kb5gffoD77w/aYtbcxhzHi8hzOb3AGFMi\nl3OMAYYC4zK9JwoYBtwAbAUWGGO+FJGVxpguwKXAqyKyDdBlvSpXOtYUuubOtd95tWrZxfzpaxbz\nQ+tBaPtt6288NP0hokwUs+q+wSU9E+Gaa+xGucWLBzWWHFuOIvJ4bifI7TUiMg/Yl+VwQ2CNiGwQ\nkRPAJKCN9/XjReQR4Jgx5l0gTluWSoWfgwehRw/o0AFeegk+/bRgiVGFrt1HdtMtuRutJrbiwcu7\n8+ORTlxyZx8YNAjefz/oiRF8nK1qjHkJ+D8R2e8tlwb6icgz+bxuRWBTpvJmbMLMICJ7gQd9OVlC\nQgKxsbEAREdHExcXl/HrMX29i5a1rGX3lA8diqdHD6hb18N778HNN/vn/OnHnP77tOxbeeasmSSv\nTmbCoQl0qtOJUbFvclbv4UQdOQI//4xn82bw8fP0eDwkJSUBZOSDgvBpnaMx5ncRuTTLsUUi4tMc\nMmNMDJAsInW95XZAMxHp5i13BhqKSO88/wE6IUepkJG+mH/hQhg1KvvF/Cr8/bTpJx6a/hClipVi\naIuh1P07xe4JeMst8MorUKxYgc4f6Ak56QoZYzIiNcacCRQk8i1AlUzlSt5jSuVL+i9I5U7pi/nr\n1oXYWPjzz8AkRq0H7rf98Hbu/uJu2k9uz+ONH8fTZRZ1x0y3SfHtt2HIkAInRn/wdROAj4CZxpgx\n3vI9wNg8XMdw6sSaBUA1b4tyG9AB6JiH851Ct49Tyr3WrbOL+Xftgq+/1jWLkerEyRMMmz+MF+e+\nSNdLu7LioRWU3H8EWraElBQ76aZKldxPlAtPsLePM8Y0B270Fr8TkW99fN8EIB4oC+wABorIGGNM\nC2AItvU6WkQG5zH29PNrt6pSLnTypG0IvPgiPPYYPPIIFCnidFTKCT+s+4FeX/fivJLnMbTFUGqW\nq2nX69x1FyQk2Ik3hf27YVtBu1XzkhxjgItE5HtjTHGgkIgcyu+F/UWTo1Luk76Yv0QJu5j/oouc\njkg5YVfKLvp804cfN/3Im83e5Naat2JOnoTERPjgA7uL/I035nqe/AjKmKMx5n5gCpC+E05F4Iv8\nXtTfEhMTdawhwunn7w5Hj8Kzz566mD+YiVHrgTuICJ8s+4Q679bh/JLns+KhFbS9uC1myxY72Dx/\nPvz+e0ASo8fjITExscDn8XW26h/YpRa/ps9aNcb8KSJ1ChxBAWnLUYEu/naDefPsYv6LL4Zhw+D8\n84Mfg9YD5+04vIMe03uwfNdyxrQZwxWVrrBPJCfbCtKnDzzxBEQFdmvvoHSrGmN+FZFG6Us6jDGF\ngUXpSzOcpMlRKWcdPAj9+8MXX8DQodC2rdMRKSeICJOWTqLvt325N+5eBsYP5IzCZ8Dx4zYZfvYZ\nTJgATZoEJZ5g3bJqtjHmKeBMY8z/gB5Acn4vqpQKD199ZXe5adYMli6F0qWdjkg5YduhbTw47UH+\n2vsXX3X8igYVG9gnFi2yg89Vqthu1DJlnA00D3xt1z4J7AL+BB4ApgP53R1HKb/Tsabg2rnTrtfu\n2xeSkuyCfjckRq0HwSUijF88nnoj6lG7Qm0WdltoE2NKCjz6KLRoYbtRP/88pBIj+NhyFJE0YBQw\nyhhTBqjkpr5MXeeoVHCIwPjxdmlGQgKMHu3ItpfKBbYc3MIDXz3AxgMb+frOr7n8/MvtE19/bbsT\nrrrKdieULx/UuIK6ztEY4wFaY5PpQmAn8JOIPFzgCApIxxyVCo716+1i/p07bVLUxfyRSURI+iOJ\nJ75/gh4NevDU1U9RtFBRuzfgww/DL7/AiBHQtKmjcQZr+7izReQg0BYYJyKNsLebUkqFuZMn7Y5e\n9evD9dfbWfiaGCPTpgObaDmhJW/Pf5sZXWaQGJ9I0agids1inTpQubJtLTqcGP3B1+RY2BhzHtAe\n+CqA8SiVLzrWFBh//gmNG9uZqD//bCcdunmXG60HgSEijFo4istGXkbjSo2Zf9984s6Ng9Wr7S+m\nESNgxgy7YXiY9LP7Olv1OeBbYJ6ILDDGXACsCVxYSiknHTsGL7xgv/Neegm6dg34sjTlUhv2b+D+\n5PvZ+89eZt01izrn1LHLM15+wXYpPPss9OwJhQo5Hapf+bx9nFvpmKNS/vXjj3b2fc2aMHy4M4v5\nlfPSJI2RC0fy7A/P8sgVj/BYk8coHFUYfvrJLua/4AJbQfywWXggBHSdozGmm4iMLOhrlFLul3kx\n/9tv28X8Jt9fLSqUrdu3jq5Tu5JyIgXP3R5qVagFBw78W0Heegtuuy2sK0huHSVPGmPa5vBoB/QJ\nRqBK5UTHmgpm2jSoXdt2py5dCu3aheb3ntaDgkmTNIbPH06DUQ1oXq05P977I7XKX2J3t6lVy87O\nWrYMbr89NCtIHuQ25jgbaJXLa77zUyxKqSDbudOu0V6wwC7mv/56pyNSTlm7dy1dp3bl+MnjzLt3\nnr2t1Ob5R38vAAAgAElEQVTNdjxx9WqYNMmuXYwQOSZHEbknWIEUhG4CoPSzzxsR+PBDu4nJ3XeH\nz2J+rQd5l5qWyrD5w3hhzgs8dfVT9GnUh0KC3Sj3ueegVy/4+GMoVszpUH0S9Jsdu5VOyFEqb9av\nh+7dYft2mxQvv9zpiJRTft38K92ndaf0GaUZcfMIqpetbm/Gef/9NhmOHGlnZoWgYG0CoJSr6VhT\n7k6etPMo6teH+HjblRpuiVHrgW/2H91Pj2k9uOXjW3j0ykeZeddMqhevbCfc3HijTY4eT8gmRn/w\ndZ2jI4wxbYCbgJLAByKi45tK5cPSpXZ5RrFidiZ+9epOR6ScICJM+HMCj373KLfUuIXlPZZT+szS\n9q7UDzxgfzktWQLnnut0qI7zdW/Vc4CXgPNFpIUx5hLgShEZHegAvdePBl4VkftP85x2qyqVjWPH\n7CL+d96BF1+0CVIX80emVbtX0WN6D/b+s5cRN42gUaVGsGePHXieNctWkptucjpMvwlWt2oSdoec\n9OXAq4G+vl7EGDPaGLPDGLMky/HmxpiVxpjVxpgncjjFM8BwX6+nlLItxEsvhcWL4Y8/oFs3TYyR\n6J8T/zDghwE0+aAJraq3YsH9C2hUsaGdfVq7NpQqZbsWwigx+oOv/6mUE5FPgDQAEUkFTubhOmOA\nZpkPGGOigGHe47WAjsaYmt7nuhhj3jDGnG+MGQxMF5E/8nA9FWF0rOlfhw7ZCYa33WYnG37+OVSs\n6HRUwaH14FTf/vUtdd6tw4rdK1jcfTF9r+hL4c1b4eabbVdC+oL+kiWdDtV1fE2OKcaYsoAAGGOu\nAA74ehERmQfsy3K4IbBGRDaIyAlgEtDG+/rxIvII0A5794/bjDHdfL2eUpFq+nTbGDhyxDYGwnwT\nE5WNrYe2cseUO3hw2oO83eJtJt8+mYolzrVbH11+ud1NfuFCaNTI6VBdy9cJOY8AU4ELjTE/AuWB\n2wp47YrApkzlzdiEmUFEhgJDcztRQkICsbGxAERHRxMXF5ex3in9l6SWtRzO5Vq14unTx5b79YN+\n/dwVX7DK6cfcEk+wyzNnzeSLlV8w8fBEutfvzj3R93DGljPg6J9w//14/vkHXn+d+LvuckW8/ix7\nPB6SkpIAMvJBQfi8ztEYUxioARhglbe15/uFjIkBkkWkrrfcDmgmIt285c5AQxHpncfz6oQcFbEy\nL+a/6y4YNCg8FvOrvFuwZQHdp3WnVLFSvNPyHS4ufzEcPWpvr/LeexE3IyugG49nukghoCUQ631P\nU++F38jvhYEtQObt3Ct5jymVZ5lbC5Fi/Xp48EHYts12p4bbmsX8iMR6cOTEER7/7nGmLJ/Cq/97\nlc51O2OMgTlz7HrF2rXtrCy9vUqe+PoTIhlIAMpi1xymP/LCeB/pFgDVjDExxpiiQAds122eJSYm\nZjSvlQp3qanw6qt2Sdo114TnYn7lm7V719J4dGP2/LOH5Q8tp0u9LpgDB+yaxU6dYPBg+PTTiEqM\nHo+HxMTEAp/H13WOS9K7Q/N1EWMmAPHY5LoDGCgiY4wxLYAh2CQ9WkQG5+Pc2q2qIsb8+XZJRoUK\n8O67cOGFTkeknDJ11VTum3ofA64dwEMNHrKtxc8+s1OVW7e2ifHss50O0zEF7Vb1NTm+AswUkRn5\nvVCgaHJUkeDgQXjmGZg8GV57zTYKdBZqZEpNS2XADwMYv2Q8n9z2CVdWvhK2bLF3z1i50u6HevXV\nTofpuGBtAvAL8Lkx5h9jzEFjzCFjzMH8XtTftFtVhfPn//nn9lZ6KSn2Vnp33qmJMTvhXA8Adqbs\npNmHzfh1y68s7LaQKys2ghEjIC4O6ta1uz1EeGIMdrfqOuwaxD/d1kzTlqOC8JyIsWmT7SFbudJO\nNrz2Wqcjcr9wrAfpftn8C+0nt6dL3S48d91zFFq12vaxp6bC++/bX1AqQ7BajpuApZqFlFuF0xfi\nyZN2rfZll/27/ZsmRt+EUz1IJyIMmz+M1hNbM6zlMF68eiCFXnjRthDvuAPmzdPEGAC+bgLwN+Ax\nxnwNHEs/WMClHEqpLH7/3TYGSpSw33k1ajgdkXJSyvEU7k++n+W7lvNz15+5cOUOaHspXHCBrSyV\nKzsdYtjyteW4DpgJFCX/SzmUCphQH2tKSbEL+Zs3hx494IcfNDHmR6jXg8xW7V5Fo/cbUaxwMX6+\n/VsuHPCm3Q9w4ECYOlUTY4D51HIUkUGBDqQgEhMTiY+PD8suFRX+pk2Dhx6yvWRLl0L58k5HpJz2\n6fJPeXDag7x4/Yvct7kCJq4+NG1qK0iZMk6H52oej8cvP5JynJBjjBkiIn2NMcl4Nx3PTERaFziC\nAtIJOSpUbdsGffrAokV2zeL//ud0RMppJ06eoP/M/ny64lM+v/Zd4l76wHafjhwJ113ndHghJdDb\nx433/u9r+b2AUupUaWn2u+7ZZ+344tixcOaZTkelnLbt0DbumHIHJYoU58+ifTmr6V12L1StII7I\nccxRRBZ6/xknIrMzP4C4wIenlG9CZaxp6VK46ioYP96OK774on7v+VOo1IOs5myYQ/1R9Wlf9FKm\njz7GWR98CN99By+9pBXEIb5OyLn7NMcS/BiHUmHtn3/gqadsz9jdd8PcuXY/aBXZRITXf3qdjpNu\n44etTenZ5yNM69bwyy9Qr57T4UW03MYcOwKdgKuAuZmeKgmkicgNgQ0vdzrmqNzu+++he3e7OfiQ\nIXDeeU5HpNzg4LGD3PvlvZRYvJxRXwpFK8XY3W78cC9CFfgxx5+AbUA54PVMxw8BS/J7UaUiwc6d\n0K+fbSW+8w60bOl0RMotlu1cRpfxt/LqnDO4/te9mNdf1w1zXSa3MccNIuIRkSuzjDkuEpHUYAWp\nVG7cNNYkAh98AHXqwLnn2v1QNTEGh5vqQXYm/jmR555qzOw39nFD9KWYpUt1w1wX8vVmx22BV4AK\n/HtfRhGRUgGMzWe6zlG5xapV9lZ6KSnw7bd2P2ilAI6fPM7AT3pwxesfM27X2RQb84Fdu6j8Kijr\nHDNeZMxfQCsRWVHgK/qZjjkqNzh2DF5+GYYNgwED7KL+QoWcjkq5xab9G/ng0evpM3kTZ9zTjTNe\nHGz3CFQBE+gxx3Q73JgYlXKD2bNta/Hii+0dgypVcjoi5Sazvx+NebAH3U1ZSs2cR1T9Bk6HpHzg\n61KO34wxHxtjOhpj2qY/AhqZUnngxFjT3r3QtSt07mxvuv7555oYneamMcfUY/8w477rqHNLNyrd\ncR/nLN+oiTGE+NpyLAUcATJ3kAvwmd8j8jLG1AT6AGWBWSIyIlDXUiovROCjj+Cxx6B9ezvhppQr\nRt+VW+yZ+RUHEjoQXeYM0ub/ygWX1Hc6JJVHPo05OskYY4CxInJXNs/rmKMKmrVr4cEH7TKNUaOg\ngTYEVGYHDrC5590UnprMvD5tuXXgRAoV8rUNovwpKDc7NsaMMcZ8kPXh43tHG2N2GGOWZDne3Biz\n0hiz2hjzRDbvbQV8BUz35VpKBcrx43bCTaNGdoLhb79pYlSZiJD26RQOXlQFz5oZrPhhMrc9N1kT\nYwjzdczxK2Ca9zET28162Mf3jgGaZT5gjIkChnmP1wI6ertRMcZ0Mca8YYw5T0SSReQmoLOP11IR\nKpBjTT/9ZHe3mTvXJsVHH4XC+p3nSo6MOW7axLFWLdncO4H+XWO4bsYarrtMp2SEOl/v5/hp5rIx\nZiIwz8f3zjPGxGQ53BBYIyIbvOebBLQBVorIeGC8MeZaY8yTQDFsUlYqqPbvh/794csv7bZvt9+u\n67RVJidPwrBhnBg0kGENhb2juvNW88EUjtJfTuEgv5/iRdgNAfKrIrApU3kzNmFm8N75Y7YvJ0tI\nSCDWux9hdHQ0cXFxGRsCpP+S1LKWfS2LwK5d8Tz8MFx+uYeRI+Hmm90Tn5azL6cfC/j1oqORbt2Y\nvG8Lg5qmMXjQR7Sq0crxvz+Syx6Ph6SkJICMfFAQvm4CcIhTb3a8HeiftUWZw/tjgGQRqesttwOa\niUg3b7kz0FBEeucxfp2Qo/xqwwbo0QPWr7f3XGzSxOmIlKukpMCgQaQljeGdtpUZd1khPmk/mdjo\nWKcjU1kEfEKOd7ZoLREplelR3dfEmI0tQJVM5UreY0rlS/ovyPxKTYXXX7dji02a2Juva2IMPQWt\nBzn65huoU4c9f/3JFX1KsLrNVcy9d54mxjCVa7eqiIgxZhpQpwDXSd+PNd0CoJq3RbkN6AB0zO/J\ndW9VVRALFkC3blC2rL2NXrVqTkekXGXHDnj4YeSXX5j28M3ce3QSw1sO5/ZatzsdmToNT5D3Vh0L\nDBORBXm+gDETgHjsYv4dwEARGWOMaQEMwbZeR4vI4Lye23t+7VZV+XLoEDzzDHz8Mbz6qt3pRifc\nqAzpt1fp35/jd93JA5dvZdGBlUy+fTLVy1Z3OjqVi2DtrdoIuNMYswFI4d+7ctTN7Y0i0imb418D\nX/saqFL+9OWX0KsX3Hij3eGmbFmnI1KusnKl3TD36FH++vhdWi1/hqtKXMUvt/3CmUXOdDo6FQS+\nJsdmub/EOdqtqjLPUMzJ5s02KS5fDuPGgVaZ8OJrPcjWsWN2o1zv7VXGNT6LfrO689r/XuPuuLv9\nFqcKnKB2q7qZdqsqyP1L8eRJeOcdeO45ezupJ5+EM84IXnwqOAqUHOfMsa3FGjU4+sar9Fz6Cj9u\n+pHJt0+mdoXafo1TBV5Bu1U1Oaqw98cf9jvvjDPgvfegZk2nI1Kusm8fPP44fP01DB3K6mtqcfvk\n26lVvhYjW43krKJnOR2hyoeg7K2qVChKSbF3zmja1M5G/eEHTYwqExGYNAkuuQSKFYNly5hcPZWr\nPriKHvV78FHbjzQxRjDd50iFhazdaV9/bRfzN2kCS5dChYLs56RChs/dquvW2QqyZQt8/jnH6l/K\nozMeZfpf0/mm8zdcdt5lAY9VuVtYtBwTExMDu/hXhYzt26FDB+jZ03ahfvihJkaVSWoqvPaavaXK\ntdfCwoWsr3kuV4+5mi2HtrCw20JNjCHO4/GQmJhY4PPomKMKC2lp8P77dt1i167w7LNQvLjTUSlX\nSd/toXx5ePdduPBCklclc1/yfTzZ5En6XtEXowtdw0aw1jkq5VqLF9sZqCdPwsyZUKcgezmp8HPo\nkP21NGmSbTXeeScn0lJ55rsnmLh0Il/c8QVXVr7S6SiVy4RFt6qKTNu22VZis2bQsKGHH3/UxBjp\n/jO8MnUq1KoFBw7Y3R46d2bLoa1cP+56luxcwqIHFmliVKelyVGFnCNH4PnnoXZtKFcOVq2C1q0h\nSmuzSrd1K9x2m70zdVISjBkDZcvy3drvqD+qPi2qtWBap2mUK17O6UiVS+mYowoZaWl2gs3TT0Pj\nxnYjk6pVnY5KuUpamp2JNWAAdO9uK8sZZ3Ay7STPz3meUYtG8eGtH3Jd1eucjlQFmI45qogwezY8\n8ggUKWI3Cm/c2OmIlOssWmSnKUdFgcdju1OBnSk7ufOzO0lNS2Vht4Wce9a5zsapQoJ2RClXW7MG\nbr0V7r7bLuj/+efTJ0ZdyhPBtm+He++Fm27C06SJ3QbOmxjnbpjLZe9dRqOKjfiuy3eaGJXPwiI5\n6jrH8LN3Lzz8MFx5JVxxhb1JQocOeksplcnRo/Dyy3bwuXx5O/h8000QFUWapPHKvFe4ffLtjGo1\niheuf4HCUdpRFgl0naOXjjmGl+PH7QbhL70E7drBoEG6iF9lIQKffWa7EuLi7M04L7ww4+m9/+zl\n7i/uZs+RPXx828dUPruyg8Eqp+iYowoLIvYei489BhddZPdB9faMKfWv33+Hvn1h/36768P115/y\n9Pwt82k/uT3tLm7H4PaDKVKoiEOBqlCnyVE5btEiO9lmzx57G71m+bh7aIHv46fcbccOO/P0q6/s\nfce6doVChQD4e9/fTF01leTVyfz2028k9Uni1otvdThgFepcnRyNMcWB2cBAEZnudDzKvzZvtt93\nM2bY77t77oHCrq6RKuiOHYMhQ2zXaUICrFrFyZJnMX/L/IyEuPvIbm6ufjN9GvWh6PlFaX5xc6ej\nVmHA1WOOxphBwCFgeXbJUcccQ8/hw/a7btgwuxTtySehZEmno1KuIgKff2772WvX5shLzzGj0DqS\nVyXz1ZqvqFCiAq2rt6Z1jdY0qNiAKBMWcwuVH7l+zNEYMxq4GdghInUzHW8ODMHOmB0tIq9ked+N\nwHLgDEDnKIaBkydh7Fi7zeV119nhoypVnI5Kuc7ixdC3Lyd2bmdGv9a8G72GOVOvpmHFhrSu0Zpn\nrnmGqqV19wcVWAFvORpjrgIOA+PSk6MxJgpYDdwAbAUWAB1EZKUxpgtwGVAKOADUAo6IyGkHEbTl\nGBpmzoR+/eCss+CNN6BhQ/+eX8ccQ5/s2MGefj04Y/oMhrYswxuXHKRpzZa0rt6aZtWaEX1GdK7n\n0Hqg0rm+5Sgi84wxMVkONwTWiMgGAGPMJKANsFJExgPj019ojLkL2B3oOFVgrFxpe8aWL4f/+z9o\n21bXKqp/HUs9xpzV33H49Ze49uNf+bJBSdaO6kLTy9uztXITnW2qHOPU9IeKwKZM5c3YhPkfIjIu\nt5MlJCQQGxsLQHR0NHFxcRm/HtM3B9BycMu1a8czaBCMG+ehUyeYMiWeYsXcE5+WnSsfOHqAg+cd\nZOqqL9k36ise+C2NuFrV2Pt9Mhf8cyYXGkN8bP7On37MTX+vloNT9ng8JCUlAWTkg4IIyoQcb8sx\nOVO3ajugmYh085Y7Aw1FpHc+zq3dqi5y7BgMHQqvvAIdO9r9n8vpjQ8i3uo9q5m6aipTV01l8Y7F\n3BtVn8embKPC4TQKD3kbmjZ1OkQVZgrarerUFK8tQOapGJW8x/JFt49znghMmQKXXGK3tpw7F95+\nO3iJUT9/d0lNS2Xuhrk8NuMxagyrwXVjr2Pt3rUMuORB9vzdnjdfX8r5CT0pvGSpXxOj1gPlCaXt\n44wxsdiWYx1vuRCwCjshZxswH+goIivycW5tOTps/ny7iP/wYXj9dbjhhuDHkLkrTTnj0LFDfLv2\nW6aumsr0NdOpcnYVWtdoTavqrbisbG3MsGH2PmN33gkDB0Lp0n6PQeuBSlfQlmMwZqtOAOKBssAO\n7IL+McaYFpy6lGNwPs+vydEhGzdC//727kAvvAB33ZWxaYmKEBsPbCR5VTJTV0/l500/06RKE1pV\nb0Wr6q3snqYikJxspypXr25/PdWs6XTYKgK4PjkGmibH4Dt0yDYARoywt8977DG7REOFvzRJY9G2\nRRm702w+uJmWF9nlFk0vbErJYpl2c/jzT9ulsGWLXb/TXHeuUcHj+qUcwZCYmEh8fLx2pwRYaip8\n8IHtEWvWzK7VrlTJ6ags7U4LnH9O/MOsdbNIXp1M8upkShUrRavqrRjaYihXVrqSQlFZugt27bKV\nZMoUOyPrgQfsXaqDQOuB8ng8fhl71paj8sm8efDgg1C2rO0Zu/xypyM6lX4p+teOwzuYtmYayauT\nmbVuFpeee6ntLq3Riuplq5/+TcePw/Dh9n5jnTrZBFmmTFDj1nqg0mm3qibHoJgzB/btg9atdRF/\nOBIRlu9antFdunzXcppe2JTWNVrToloLyhYvm9ObYdo0O654wQW2C/Xii4MXvFKnoclRk6NS+XLi\n5AnmbpybMaEmNS01YzPva2OvpWihormfZNkyO664caNNii1aBD5wpXygyVGTo0K703y1/+h+vvnr\nG6aumso3f31DtTLVaF3DJsQ6FepgfO0W2L3bdptOngzPPGP73IM0rpgTrQcqnU7IQSfkKJWTv/f9\nndE6XLBlAdfGXkvr6q15relrnF/y/Lyd7MQJeOcdu3bnjjtgxQo7EK2US+iEHC9tOSp1qjRJ49fN\nv5K8Opmpq6Zm3Ay4dY3W3HjBjRQvUjx/J54+3XahxsTYLtRatfwbuFJ+pN2qmhyVIuV4Ct///T1T\nV0095WbArWq0omHFhgW7GfDy5Xayzd9/26TYsqXOylKup8lRk6MissaaTpw8wdZDW9l0cBNLdy7l\nq9VfMWfDnIybAbeq3so/NwPeswcGDYKJE+Hpp6FHDyjqwyQdB0VSPVA50zFHpcJImqSxK2UXmw5u\nYuOBjWw6sOnffx/cxKYDm9iZspNzzjqHyqUqc1HZi+hctzMftv3Qp5sB++TECXj3XTuuePvtdlxR\nb62iIoy2HJUKogNHD5yS6DL+7S1vPriZksVKUrlUZSqfXZkqpapQ+ezKVC5VmSpn23+fX/J8CkcF\n6HftN9/YccWKFeHNN6F27cBcR6kA025VTY7KJY6mHs1o6WVNfOmtQEH+TXTpCTDTvyuVqpT/CTMF\nsXKlTYp//WW3QLr5Zh1XVCFNk6MmR0Xgx5pS01LZdmhbjt2dB44doFKpShmJ7nRJ8OxiZ/u+ljAY\n9u6144oTJthbrPTs6fpxxZzomKNKp2OO6DpHVTAiwu4ju3NMfNsPb6d8ifKndHdeUPoCro25NqO7\ns0KJCgWbFRpMqanw3nvw3HNw6612Rmr58k5HpVSB6TpHL205qtwcOnbolESXNfFtOriJ4kWK5zrO\n59N2aqFgxgx4+GE491w7rli3rtMRKeV32q2qyTEoth7ayuaDm50OI1tHThzJdpzvRNqJHMf5Kpeq\nTImiJZz+EwJv1Sq7XnHlSjuuqLvIqzCmyVGTY1CM+X0M7/72rtNhZOvoX0ep06jOaZNg6TNKu2uc\nL9j27bPdp+PHw5NPQq9eUKyY01EFhI45qnRhO+ZojLkWeB5YBkwUkTkOhxTR7rn0Hu659B6nw8iW\nfimeRmoqjBxpJ9zccosdV6xQwemolAoJrk2OgACHgGKAe/vzlCtoYszi++/tuGK5cnaMsV49pyMK\nCq0Hyl8C3q1qjBkN3AzsEJG6mY43B4YAUcBoEXklm/dXAN4Qkc7ZPK/dqkqlW7PGjisuWwavvWZb\njJHcpawiVkG7VYMx73wM0CzzAWNMFDDMe7wW0NEYU9P7XBdjzBvGmPO8L98PhMk0QRUo/pi6HdL2\n77dJ8cor4aqrbBfqrbdGXGKM+Hqg/CbgyVFE5gH7shxuCKwRkQ0icgKYBLTxvn68iDwCXGGMGQGM\nxSZSpVRWqakwYgTUqAEHDsDSpfD442E74UapYHFqzLEisClTeTM2YWYQkc+Bz305WUJCArGxsQBE\nR0cTFxeXMfaQ/ktSy1oOq/KVV8KUKXiefRZKliT+m2/g0kvt8ytXOh+fQ+X0Y26JR8vBK3s8HpKS\nkgAy8kFBBGUphzEmBkhOH3M0xrQDmolIN2+5M9BQRHrn49w65qgix6ZNdmeb99+3m4L37g2tWkVc\n96lSuQmFMcfT2QJUyVSu5D2WL4mJiRm/IFRkCuvPXwRmzoS2be2s0wMH4Icf7IxUXch/irCuB8on\nHo+HxMTEAp8nWC3HWGzLsY63XAhYBdwAbAPmAx1FZEU+zq0tR3VKV1rYOHgQxo2Dd96BqCh46CHo\n3BlKlnQ6MtcKy3qg8sX1O+QYYyYA8UBZYAcwUETGGGNacOpSjsH5PL8mRxVeli2D4cNh4kS48Uab\nFK+9VluISuWB65NjoGlyVGHhxAn48kubFFeuhG7d7KNiRacjUyokheqYo1/pmKMK2c9/+3a772nV\nqvDWW9C9O2zYYLd808SYZyFbD5TfhNSYYyBpy1FBiI01icCPP9pW4jffQPv20KNHxGzxFkghVQ9U\nQGm3qiZHFSpSUmDCBBg2DP75xybEhASIjnY6MqXCjiZHTY7K7dassTNOx42zW7s99JCdaBMVFqMa\nSrmSjjkqhQvHmk6ehORkaN4cmjSx27ktXGgn3TRtqokxQFxXD1TIcvMtq3yWmJhIfHy8jjUo5+3e\nDaNH2/1OK1SwrcQvvoAzznA6MqUigsfj8cuPJO1WVcofFiywE2y+/BLatLFJsUEDp6NSKmLpmKMm\nR+WUo0fhk0/sBJtdu+DBB+Hee+0NhpVSjtIxR6UI8ljT+vXw5JNQpYqdffrss/DXX/ZWUZoYHaVj\njspfNDkq5Yu0NJgxw270Xb8+HD9u1yp+8429K0ahQk5HqJTyI+1WVSon+/dDUpJdilG8OPTsCR07\nQokSTkemlMpBQbtVw2K2qlJ+t2SJnWDzySfQogWMGQONG+vm30pFCO1WVWHBL2NNx4/DpElw9dXQ\nsiVUqgQrVthxxSZNNDGGAB1zVP4SFi1HXeeoCmTLFhg5EkaNgpo1oW9fO7ZYpIjTkSml8kjXOXrp\nmKPKFxGYM8cuw5g5044j9ugBtWo5HZlSyg90zFGpvDh8GMaPt+OJaWl2sf7o0VCqlNORKaVcRMcc\nVVjItRtl5Uro1QtiYuD77+Htt2HZMpscNTGGDR1zVP7i2pajMcYAzwOlgAUiMt7hkFSoSU21m38P\nHw5Ll8L998PixXaijVJK5cC1Y47GmFuAW4DdwDQR+SGb1+mYozrVzp3w/vt28+/KlW3rsF07e2cM\npVREcP32ccaY0caYHcaYJVmONzfGrDTGrDbGPHGat9YAfhSRR4EegY5ThTgR+Pln6NwZatSAdetg\n6lS7i02nTpoYlVJ5EowxxzFAs8wHjDFRwDDv8VpAR2NMTe9zXYwxbwBbgX3et5wMQpwqlBw7Zhfq\nT5gATz2Fp0YN6NIFLrsM/v7bLsuIi3M6ShVkOuao/CXgY44iMs8YE5PlcENgjYhsADDGTALaACu9\nY4vjjTFnAkONMVcDswMdp3Kp1FRYu9aOGWZ+rF8PF1xgl17Urg3dusEjj+hNhJVSfuHUhJyKwKZM\n5c3YhJlBRP4B7vPlZAkJCcTGxgIQHR1NXFxcxoYA6b8ktezy8jXXwMaNeCZOhHXriD9yBJYuxbNi\nBZQtS3yDBlC7Np6aNaFFC+LvvBOKFXNP/Fp2RTn9mFvi0XLwyh6Ph6SkJICMfFAQQZmQ4205JotI\nXZUrzjEAAAjeSURBVG+5HdBMRLp5y52BhiLSOx/n1gk5oUQEtm+3rb9ly/5tCS5bBmefbVuB6Y9a\nteCSS3STb6VUnoXqJgBbgCqZypW8x/JFt49zqb17T02A6Q9j/k2A9etDQoJNhKVL5/tSmVsLKnJp\nPVCeUNo+zhgTi2051vGWCwGrgBuAbcB8oKOIrMjHubXl6LTDh2H58v8mwcOH/x0TzPyoUMHvm3jr\nl6ICrQfqXwVtOQY8ORpjJgDxQFlgBzBQRMYYY1oAQ7AzZkeLyOB8nl+TY7AcO2Z3msncFbp0qe0m\nrVnz367Q9CRYpYreyUIp5QjXJ8dA0+QYJG+/DY8/bmeIZm0JXnABFHbtZktKqQgUqmOOfqVjjkGQ\nkAAPPODaxfTanaZA64EKsTHHQNKWowL9UlSW1gOVTrtVNTkqpZTKwvV7qyqllFKhRpOjCgv+GGNQ\noU/rgfKXsEiOiYmJ+h+FUkopPB4PiYmJBT6PjjkqpZQKOzrmqJRSSvmZJkcVFrRbXYHWA+U/mhyV\nUkqpLHTMUSmlVNjRMUellFLKzzQ5qrCgY00KtB4o/wmL5KjrHJVSSoGuc8ygY45KKaWy0jFHpZRS\nys80OaqwoN3qCrQeKP9xbXI0xlxljHnXGDPKGDPP6XiUu/3xxx9Oh6BcQOuB8pfCTgeQHRGZB8wz\nxrQB5jsdj3K3/fv3Ox2CcgGtB8pfAt5yNMaMNsbsMMYsyXK8uTFmpTFmtTHmiRxO0QmYENgoAyOQ\nXTwFPXd+3u/re3x5XW6vye75UOw2c3M9yM858vL6/H7OuT0fivUA3F0XQrEe5DWOvAhGt+oYoFnm\nA8aYKGCY93gtoKMxpqb3uS7GmDeMMecZYyoD+0UkJQhx+l04/YeQl/c4kRzXr1+f6zWd4uZ6kJ9z\nuOFLMRTrAbi7LoRiPchrHHkRlKUcxpgYIFlE6nrLVwADRaSFt/wkICLySpb3JQLfiMgvOZxb13Eo\npZT6j4Is5XBqzLEisClTeTPQMOuLRCQxtxMV5I9XSimlTse1s1WVUkoppziVHLcAVTKVK3mPKaWU\nUo4LVnI03ke6BUA1Y0yMMaYo0AGYGqRYlFJKqRwFYynHBOAnoLoxZqMx5h4ROQn0AmYAy4BJIrIi\n0LEopZRSvgj5jceVUkopf3PtDjn5ZYwpDrwDHANmi0hIbiCgCs4YUxV4GiglIu2djkc5w7vL1k1A\nSeADEfnO4ZCUA7xr6fsAZYFZIjIix9eHW8vRGNMZ2Cci04wxk0Skg9MxKWcZYz7R5KiMMdHAqyJy\nv9OxKOcYYwwwVkTuyul1rl/KkY/t5yrx7xrKk0ELVAWcH7YiVGGgAPXgGWB4cKJUgZafemCMaQV8\nBUzP7fyuT47kcfs5bGKslP7SYAWpgiKvdSHjZcEJTwVJnuuBMWYwMF1E9LYd4SPP9UBEkkXkJqBz\nbid3fXL03p1jX5bDDYE1IrJBRE4Ak4A23uc+B24zxgwHkoMXqQq0vNYFY0wZY8y7QJy2KMNHPupB\nL+AG7PdCt6AGqwImH/XgWmPMW8aYEcC03M4fqhNyst1+TkSOAPc6EZRyRE51YS/woBNBqaDLqR4M\nBYY6EZQKupzqwWxgtq8ncn3LUSmllAq2UE2Ouv2cSqd1QYHWA2X5rR6ESnLU7edUOq0LCrQeKCtg\n9cD1yVG3n1PptC4o0HqgrEDXg7DbBEAppZQqKNe3HJVSSqlg0+SolFJKZaHJUSmllMpCk6NSSimV\nhSZHpZRSKgtNjkoppVQWmhyVUkqpLDQ5KlUAxpg0Y8yrmcr9jDEDsnltG2PMM366bh9jzP+3d3ch\nVlVRAMf/fyuwJqZoHvowwgINIkYbLZjEiIiihwyir4copMIgQsweIvqgHqKJIiSyGGskkoKiehAq\nKrMkEczPGZ1eKqGHiIIKxxgFc/VwzoUzx3sn8trcGVi/l3vP3mvvs+fCsGbfvefs2ZPUDzY5uuu/\n3uMZ9boTaPeQuryde6fUafkQgJTaoI4DPwNXRsTv6mqgKyKebRK7Fbi5PC2k3fseABY160udFRHH\n2r3HiVJPB7ZGRF+nxpBSu3LmmFJ7jgKDwCOTBanzgMONZKauV9eq29Tvy7Pm3lRH1aFKu7XqdnVE\nfbosexi4ANisbirLxtQX1d1Av7pZ7VMvKk9EP8fCFvX62thmleMZVveqKytjvFVdpO5Wd5Uxf5f1\nl6ifqN+qX6vzASJiHDigLj4pn3BKHTBTz3NMaboI4FVgRB2YJG4JsKtWdnZE9KvLKB6O3B8Ro+oO\ntTcihoHHI+LP8oTzTeoHEfGKugq4NiIah712Adsi4lEALZ7FHBE/qc8DrwPbgf0R8UVtHAuBORHR\nW7btnvADRuwErijrXgA+LqsGgRUR8YN6FfAaxaHCADuBpcCOST6TlKatTI4ptSkiDqlvASuB8RZh\n5wO/1co2lq8jwC8RMVpe7wfmAsPAXeoDFL+r5wGXAfs4/jSCo8CHLcY3pN4BrKBIhHU/AheraygS\n32fN+lHvpEiSN6hdwNXA+zYyMZxWCf8VuLRZPynNBJkcUzo51lDMDIda1I8D3bWyI+Xrscr7xvWp\n6lxgNcXa4kF1PdBqE87haLGBoFwDvLC8PBP4q1pfzkwXADcCDwK3A/fX+rgceApYGhFRzmT/mGRd\ncTat/1BIadrLNceU2iNA+fXme9SSSsV3wLx/66emGzgEjKnnAjdV6g4yMdk2a98wAGygSG5vHHdj\n7QFOiYiPgCeAvlr9WcA7wD2NNdOIGKNYV7ytEtdbaTafYoab0oyUyTGl9lRnay8BPbWyhi1M/Eqz\nHhP19+Wa4x6KxLoB+KYSsw74tLEhp1V/6jXAYmAgIt4Fjqj31mLnAF+Vm3neBh6r9XkLxenq6xob\nc8ryu4H71D3qPmBZpc8lwOekNEPlv3KkNEXUl4GNEfFlp8fyf1IXAqsiop6EU5oxcuaY0tR5Djij\n04OYAj3Ak50eRErtyJljSimlVJMzx5RSSqkmk2NKKaVUk8kxpZRSqsnkmFJKKdVkckwppZRq/gGk\n4a0VB+09mwAAAABJRU5ErkJggg==\n",
"text/plain": [
"<matplotlib.figure.Figure at 0xd50ba58>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plot_times(times, cols=['pure python', 'c', 'julia'], name='runtimes_5')"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.5.1"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
@dilawar
Copy link

dilawar commented Dec 31, 2016

I would be cool to see how PyPy performs.

@unyty
Copy link

unyty commented Mar 20, 2018

A perfect exercise for beginners

@t184256
Copy link

t184256 commented May 6, 2018

But why do you compile Cython code without optimizations?

@ChrisRackauckas
Copy link

You should try the fast version of Julia, i.e.:

using LoopVectorization

function det_by_lu(y, x, N)
    y[1] = 1.

    @turbo for k = 1:N
        y[1] *= x[k,k]
        for i = k+1:N
            x[i,k] /= x[k,k]
	end
        for j = k+1:N
            for i = k+1:N
                x[i,j] -= x[i,k] * x[k,j]
            end
        end
    end
end

This is quite a bit faster.

@pddshk
Copy link

pddshk commented Nov 20, 2021

Why don't also compare with Julia's lapack?

using LinearAlgebra

A = rand(1000,1000)

@elapsed lu(A)

@ChrisRackauckas
Copy link

The pure Julia RecursiveFactorization.jl is faster than LAPACK BTW. https://github.com/YingboMa/RecursiveFactorization.jl it would be nice to add it to the benchmarks.

@pddshk
Copy link

pddshk commented Nov 20, 2021

And here's some improvements to your Julia code. The result of the last expression is vector of elapsed times.

You can also add @fastmath @simd in det_by_lu! after @inbounds it gives small speedup

function det_by_lu!(x::AbstractMatrix{T}, N = size(x, 2)) where T <: Number
    y = one(T)
    @inbounds for k in 1:N
        y *= x[k,k]
        @views x[k+1:N, k] ./= x[k,k]
        for j in k+1:N, i in k+1:N
            x[i,j] -= x[i,k] * x[k,j]
        end
    end
    y
end

function run_julia(A, N = size(A, 2))
    loops = max(10_000_000 ÷ N^2, 1)
    B = similar(A)
    elapsed = 0.
    for _ in 1:loops
        copy!(B, A)
        elapsed += @elapsed det_by_lu!(B, N)
    end
    elapsed / loops
end

map([5, 10, 30, 100, 200, 300, 400, 600, 1000]) do N
    run_julia(rand(N,N))
end

UPD. Forgot to say that you may also take a look at BenchmarkTools.jl, that provides @benchmark and @btime macro

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment