Skip to content

Instantly share code, notes, and snippets.

@WillieMaddox
Forked from benjaminirving/README.md
Last active August 29, 2015 14:15
Show Gist options
  • Save WillieMaddox/27fda24dfc68ffda8840 to your computer and use it in GitHub Desktop.
Save WillieMaddox/27fda24dfc68ffda8840 to your computer and use it in GitHub Desktop.
# Python running example
from __future__ import print_function
import numpy as np
from rect import PyRectangle
# Initialising the wrapped c++ function
R1 = PyRectangle(0, 0, 9, 9);
#Test1: Doing the area example calculation
print("Test 1, Area: ", R1.getArea())
#Test2: Passing a list from python to c++
list1 = [1,2,3,4,5]
print("Test 2, Sum list: ", R1.sum_vec(list1))
#Test3: Passing a numpy array from python to c++
list2 = np.array([1,2,3,4,5])
print(" Test 3, Sum list: ", R1.sum_vec(list2))
#Test4: Passing a 2D list from python to c++
list3 = [[1, 2, 3], [4, 5, 6]]
print("Test 4, Sum list: ", R1.sum_mat(list3))
#Test5: Passing a 2D numpy array from python to c++
# Passing by value makes a second copy so best to pass by reference as demonstrated in the next example
list4 = np.array([[1, 2, 3], [4, 5, 6]])
print("Test 5, Sum list: ", R1.sum_mat(list4))
#Test6: Passing a 2D numpy array from python to c++ as a constant reference
list5 = np.array([[1, 2, 3], [4, 5, 6]])
print("Test 6, Sum list: ", R1.sum_mat_ref(list5))
#Test7: Returning a 2D numpy array from c++
list6 = np.array([[1, 2, 3], [4, 5, 6]])
print("Test 7, Sum list: ", R1.ret_mat(list6))
# This should work with any n-dimensional array
# distutils: language = c++
# distutils: sources = Rectangle.cpp
# Cython interface file for wrapping the object
#
#
from libcpp.vector cimport vector
# c++ interface to cython
cdef extern from "Rectangle.h" namespace "shapes":
cdef cppclass Rectangle:
Rectangle(int, int, int, int) except +
int x0, y0, x1, y1
int getLength()
int getHeight()
int getArea()
void move(int, int)
double sum_vec(vector[double])
double sum_mat(vector[vector[double]])
double sum_mat_ref(vector[vector[double]] &)
vector[vector[double]] ret_mat(vector[vector[double]])
# creating a cython wrapper class
cdef class PyRectangle:
cdef Rectangle *thisptr # hold a C++ instance which we're wrapping
def __cinit__(self, int x0, int y0, int x1, int y1):
self.thisptr = new Rectangle(x0, y0, x1, y1)
def __dealloc__(self):
del self.thisptr
def getLength(self):
return self.thisptr.getLength()
def getHeight(self):
return self.thisptr.getHeight()
def getArea(self):
return self.thisptr.getArea()
def move(self, dx, dy):
self.thisptr.move(dx, dy)
def sum_vec(self, sv):
return self.thisptr.sum_vec(sv)
def sum_mat(self, sv):
return self.thisptr.sum_mat(sv)
def sum_mat_ref(self, sv):
return self.thisptr.sum_mat_ref(sv)
def ret_mat(self, sv):
return self.thisptr.ret_mat(sv)
/*
Passing variables / arrays between cython and cpp
Example from
http://docs.cython.org/src/userguide/wrapping_CPlusPlus.html
Adapted to include passing of multidimensional arrays
*/
#include "Rectangle.h"
using namespace shapes;
Rectangle::Rectangle(int X0, int Y0, int X1, int Y1)
{
x0 = X0;
y0 = Y0;
x1 = X1;
y1 = Y1;
}
Rectangle::~Rectangle()
{
}
int Rectangle::getLength()
{
return (x1 - x0);
}
int Rectangle::getHeight()
{
return (y1 - y0);
}
int Rectangle::getArea()
{
return (x1 - x0) * (y1 - y0);
}
void Rectangle::move(int dx, int dy)
{
x0 += dx;
y0 += dy;
x1 += dx;
y1 += dy;
}
/*
Inputting a 1D vectoror list and returning its sum
*/
double Rectangle::sum_vec(std::vector<double> sv)
{
double tot=0;
int svs = sv.size();
std::cout << "vector length " << svs << std::endl;
for (int ii=0; ii<svs; ii++)
{
tot = tot + sv.at(ii);
}
return tot;
}
/*
Inputting a 2D vector or list and returning its sum
*/
double Rectangle::sum_mat(std::vector< std::vector<double> > sv)
{
double tot=0;
int svrows = sv.size();
int svcols = sv[0].size();
std::cout << "vector length " << svrows << " , " << svcols << std::endl;
for (int ii=0; ii<svrows; ii++)
{
for (int jj=0; jj<svcols; jj++)
{
tot = tot + sv.at(ii).at(jj);
}
}
return tot;
}
/*
Passing a 2D vector by reference or list and returning its sum
*/
double Rectangle::sum_mat_ref(const std::vector< std::vector<double> > & sv)
{
double tot=0;
int svrows = sv.size();
int svcols = sv[0].size();
std::cout << "vector length " << svrows << " , " << svcols << std::endl;
for (int ii=0; ii<svrows; ii++)
{
for (int jj=0; jj<svcols; jj++)
{
tot = tot + sv.at(ii).at(jj);
}
}
return tot;
}
/*
Inputting a 2D vector, performing a simple operation and returning a new 2D vector
*/
std::vector< std::vector<double> > Rectangle::ret_mat(std::vector< std::vector<double> > sv)
{
int svrows = sv.size();
int svcols = sv[0].size();
std::vector< std::vector<double> > tot;
tot.resize(svrows, std::vector<double> (svcols, -1));
std::cout << "vector length " << svrows << " , " << svcols << std::endl;
for (int ii=0; ii<svrows; ii++)
{
for (int jj=0; jj<svcols; jj++)
{
tot.at(ii).at(jj) = (2*sv.at(ii).at(jj));
}
}
return tot;
}
/*
Passing variables / arrays between cython and cpp
Example from
http://docs.cython.org/src/userguide/wrapping_CPlusPlus.html
Adapted to include passing of multidimensional arrays
*/
#include <vector>
#include <iostream>
namespace shapes {
class Rectangle {
public:
int x0, y0, x1, y1;
Rectangle(int x0, int y0, int x1, int y1);
~Rectangle();
int getLength();
int getHeight();
int getArea();
void move(int dx, int dy);
double sum_vec(std::vector<double> sv);
double sum_mat(std::vector< std::vector<double> > sv);
double sum_mat_ref(const std::vector< std::vector<double> > & sv);
std::vector< std::vector<double> > ret_mat(std::vector< std::vector<double> > sv);
};
}
# Cython compile instructions
from distutils.core import setup
from Cython.Build import cythonize
# Use python setup.py build --inplace
# to compile
setup(
name = "rectangleapp",
ext_modules = cythonize('*.pyx'),
)
@WillieMaddox
Copy link
Author

Is Test7 supposed to return a 2D numpy array? Because I'm getting a list. Thanks.

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