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