Daniel Haehn PRO
Hi, I am a biomedical imaging and visualization researcher who investigates how the study of brain connectivity and machine perception can help advance the understanding of biologically inspired artificial intelligence.
Staff will give feedback asap
< 6 weeks
Meetings
Functions, Classes
Arrays, Vectors
Templates
GIBBS Cluster
Cython
Run our C++ code in Python using Cython
and compare timing against NumPy
Analyze a bunch of numbers and calculate min, max, mean, stddev.
void test_get_min_float() {
std::vector<float> somevalues;
somevalues.push_back(1.1);
somevalues.push_back(2.31);
somevalues.push_back(3.4);
somevalues.push_back(-241.44);
assert(get_min_float(somevalues)==-241.44);
std::cout << "Test OK!" << std::endl;
}
Never got executed!
void test_get_min_float() {
std::vector<float> somevalues;
somevalues.push_back(1.1);
somevalues.push_back(2.31);
somevalues.push_back(3.4);
somevalues.push_back(-241.44);
float diff = std::abs( -241.44 ) - std::abs( get_min_float(somevalues) );
assert(diff < 0.0005);
std::cout << "Test OK!" << std::endl;
}
Check if we have a very small difference between two floats..
We can not just compare floats..
float onevalue = 0.33333333333333;
float secondvalue = 1/3;
if (onevalue == secondvalue) {
// cancel life-support
// ...
}
Developer is in charge of precision..
All languages do this more or less problematically!
Software Development Models
Predictive
Adaptive
As rigid as possible as flexible as needed
Templates
Generic Programming
Type-Independent
"Blueprint"
Advanced!
#include <iostream>
#include <vector>
//#define NDEBUG
#include <cassert>
template <typename T>
class Stats {
public:
T get_min(std::vector<T>);
};
template <typename T>
T Stats<T>::get_min(std::vector<T> v) {
T minvalue = v[0];
for(int i = 1; i<v.size(); i++) {
minvalue = std::min(minvalue, v[i]);
}
return minvalue;
};
void test_get_min() {
std::vector<float> somevalues;
somevalues.push_back(1.3);
somevalues.push_back(2);
somevalues.push_back(3);
somevalues.push_back(-241.3);
Stats<float> stats;
float result = stats.get_min(somevalues);
std::cout<< result << " == " << -241.3 << std::endl;
float diff = (result - -241.3);
std::cout << "Diff " << diff << "\n";
// assert(result == -241.3);
assert(diff < 0.0005);
};
void test_get_min_double() {
std::vector<double> somevalues;
somevalues.push_back(1.3);
somevalues.push_back(2);
somevalues.push_back(3);
somevalues.push_back(-241.3);
Stats<double> stats;
double result = stats.get_min(somevalues);
std::cout<< result << " == " << -241.3 << std::endl;
double diff = (result - -241.3);
std::cout << "Diff " << diff << "\n";
// assert(result == -241.3);
assert(diff < 0.0005);
};
int main() {
test_get_min();
std::cout << "OK!" << std::endl;
test_get_min_double();
std::cout << "OK!" << std::endl;
};
Templated Classes!
Cython!
Calling C++ from Python
Why?
Python code might be slow
def sum_even_no(x):
y = 0
for i in range(x):
if i%2 == 0:
y += i
return y
def sum_even_no(x):
cdef int y = 0
cdef int i
for i in range(x):
if i%2 == 0:
y += i
return y
import timeit
cy = timeit.timeit('''test_cy.sum_even_no(500)''',setup = 'import test_cy', number=1000)
py = timeit.timeit('''test_py.sum_even_no(500)''',setup = 'import test_py', number=1000)
py/cy
Cython is 18.43x faster!
Python
Cython
Python
Cython
m.pyx
m.c
m.so
Generated C++ Code
Compiled to Shared Library
But before we do this...
Python vs. cppyy Comparison by Steve Pieper, Isomics Inc.
Code?
What do we have?
stats.cc
What do we need?
setup.py
statistics.pyx
#include <iostream>
#include <vector>
#include <algorithm>
#include <cassert>
#include <cmath>
template <typename T>
class Stats {
public:
T get_min(std::vector<T> v);
T get_max(std::vector<T> v);
float get_mean(std::vector<T> v);
float get_stddev(std::vector<T> v);
};
template <typename T>
T Stats<T>::get_min(std::vector<T> v) {
T minvalue = v[0];
for(int i=1; i<v.size(); i++) {
minvalue = std::min(minvalue, v[i]);
}
return minvalue;
}
template <typename T>
T Stats<T>::get_max(std::vector<T> v) {
T minvalue = v[0];
for(int i=1; i<v.size(); i++) {
minvalue = std::max(minvalue, v[i]);
}
return minvalue;
}
template <typename T>
float Stats<T>::get_mean(std::vector<T> v) {
float sum = v[0];
for(int i=1; i<v.size(); i++) {
sum += v[i];
}
sum /= v.size();
return sum;
}
template <typename T>
float Stats<T>::get_stddev(std::vector<T> v) {
float stddev = 0;
float mean = Stats<T>::get_mean(v);
for(int i=1; i<v.size(); i++) {
stddev += std::pow(v[i] - mean, 2);
}
return std::sqrt(stddev / v.size());
}
void test_get_min() {
std::vector<float> somevalues;
somevalues.push_back(1.3);
somevalues.push_back(2);
somevalues.push_back(3);
somevalues.push_back(-241);
Stats<float> stats;
assert(stats.get_min(somevalues)==-241);
std::cout << "Test OK!" << std::endl;
}
void test_get_max() {
std::vector<float> somevalues;
somevalues.push_back(1.3);
somevalues.push_back(2);
somevalues.push_back(3);
somevalues.push_back(-241);
Stats<float> stats;
assert(stats.get_max(somevalues)==3);
std::cout << "Test OK!" << std::endl;
}
void test_get_mean() {
std::vector<float> somevalues;
somevalues.push_back(1.3);
somevalues.push_back(2);
somevalues.push_back(3);
somevalues.push_back(-241);
Stats<float> stats;
float diff = std::abs(stats.get_mean(somevalues)) - std::abs(-58.675);
assert(diff < 0.0005);
std::cout << "Test OK!" << std::endl;
}
void test_get_stddev() {
std::vector<float> somevalues;
somevalues.push_back(1.3);
somevalues.push_back(2);
somevalues.push_back(3);
somevalues.push_back(-241);
Stats<float> stats;
float diff = std::abs(stats.get_stddev(somevalues)) - std::abs(105.26712152899404);
assert(diff < 0.0005);
std::cout << "Test OK!" << std::endl;
}
int main()
{
test_get_min();
test_get_max();
test_get_mean();
test_get_stddev();
}
What do we have?
stats.cc
What do we need?
setup.py
statistics.pyx
python setup.py build_ext --inplace
.so
conda install cython
from setuptools import setup
from Cython.Build import cythonize
setup(ext_modules=cythonize("statistics.pyx"))
setup.py
statistics.pyx
By Daniel Haehn
Hi, I am a biomedical imaging and visualization researcher who investigates how the study of brain connectivity and machine perception can help advance the understanding of biologically inspired artificial intelligence.