Pybind11: Passing a Python list to C-style array - python

I would like to pass a Python list to a constructor which takes C-style arrays.
How should that work. The problem is that the C-style array is essentially a pointer. Furthermore, the array has dimension n x n, i.e. it is a multi-dimensional array.
PYBIND11_MODULE(matrix_class_bind, m){
py::class_<matrix_class<double>>(m, "matrix_class")
.def(py::init([](double x[3][3]){
matrix_class<double> new_class(x);
return new_class;}));
}
On the python side it should be something like:
import matrix_class_bind as mcb
a = [[1,2,3], [3,4,5], [1,1,1]]
mcb.matrix_class(a)

Instead of passing the matrix as a pointer, you could pass it using py::list, if your aim is to access the matrix as a C array.
class matrix_class {
public:
static const int n = 3;
int carray[n][n];
py::list list;
matrix_class(const py::list &list) : list(list) {
for (int i = 0; i < n; i++) {
py::list l = list[i].cast<py::list>();
for (int j = 0; j < n; j++){
int p = l[j].cast<int>();
carray[i][j] = p;
}
}
}
}
PYBIND11_MODULE(matrix_class_bind, m) {
py::class_<matrix_class>(m, "matrix_class")
.def(py::init<const py::list &>());
}

Related

2D C array to Numpy Array using ctypes

Hello I am trying to write a simple C function that takes two inputs (m,n) and creates a 2D - array of pointers. Now I want to call that function in Ctypes and create a numpy array from the pointers. I am however not sure how to proceed - and run into an error when calling the np.frombuffer - function. Any help is apprechiated
c- file
#include <stdio.h>
#include <stdlib.h>
#define RANDOM_RANGE 50
typedef struct {
float val;
} cell;
cell **matrixMake(int m, int n){
// the rows
cell **pRow = (cell **)malloc(m* sizeof(cell *));
// the cols
for (int i = 0; i < m; i++){
pRow[i] = (cell *)malloc(n * sizeof(cell));
}
for (int i = 0; i < m; i++){
for (int j = 0; j < n; j++){
pRow[i][j].val = (float) (rand() % RANDOM_RANGE);
}
}
return pRow;
}
Corresponding Python File
import numpy as np
from numpy.ctypeslib import ndpointer
from ctypes import *
class CELL(Structure):
_fields_ = [ ('val', c_float) ]
libc = CDLL("c_arr_multi.so")
libc.matrixMake.argtypes = [ c_int, c_int ]
libc.matrixMake.restype = POINTER(POINTER(CELL))
res = libc.matrixMake(6, 3)
x = np.frombuffer((c_float * 6 * 3).from_address(libc.matrixMake(6, 3)), np.float32).copy()
print(x)
I am simply not shure how to proceed

Incrementing a for loop upward in C

I am hoping to mimic a Python for loop with the range() function in C. I'd like to accomplish a task an increasing number of times each loop until I reach the value of a given variable, in this case 5 (for the variable h). Here it is in Python:
x = 5
y = 0
while x > y:
for i in range(y+1):
print("#",end='')
print('')
y+=1
Output:
#
##
###
####
#####
I was able to accomplish the opposite (executing something a decreasing number of times) in C, as below:
{
int h = 5;
while (h > 0)
{
for (int i = 0; i < h; i++)
{
printf("#");
}
printf("\n");
h--;
}
}
Output:
#####
####
###
##
#
When I've attempted the top version in C, with the increasing number of executions, I run into the problem of not knowing how to control the various incrementing and decrementing variables.
I suggest you should think simply:
Increment up the number of # to print
Use loop to print that number of #
#include <stdio.h>
int main(void)
{
int h = 5;
for (int c = 1; c <= h; c++) // the number of # to print
{
for (int i = 0; i < c; i++)
{
printf("#");
}
printf("\n");
}
return 0;
}
Another way is simply writing in just the same way as the Python version:
#include <stdio.h>
int main(void)
{
int x = 5;
int y = 0;
while (x > y)
{
for (int i = 0; i < y+1; i++)
{
printf("#");
}
printf("\n");
y += 1;
}
return 0;
}
The solution in C:
#include <stdio.h>
int main ()
{
int x = 5;
int y = 0;
while (x > y)
{
for (int i=0;i<y+1;i++)
{
printf("#");
}
printf("\n");
}
return 0;
}
In Python, in the for loop, the variable is initialized as zero and increments by 1 by default. But in C, you need to do it explicitly.

Multi-Dimensional array returned from C++ sends garbage when using ctypes

I'm making a Game Engine in Python. Currently it runs at 5-7 FPS, and I want to increase it. So I thought to use C/C++ for putting shapes onto frames. My frames are 3-Dimensional arrays. I want to transport theses arrays between python and C++. But When using np.ctypeslib.ndpointer the array contains garbage.
Here's the code of C++ file:
#include <iostream>
using namespace std;
int*** zeros_3d_cpp(int n1, int n2, int n3) {
int ***arr = new int**[n1];
for (int i = 0; i < n1; i++) {
arr[i] = new int*[n2];
for (int j = 0; j < n2; j++) {
arr[i][j] = new int[n3];
for (int k = 0; k < n3; k++) {
arr[i][j][k] = 0;
}
}
}
return arr;
}
extern "C" {
__declspec(dllexport) int*** zeros_3d(int n1, int n2, int n3) { return zeros_3d_cpp(n1, n2, n3); }
}
Here's the python code:
from ctypes import *
import numpy as np
lib = cdll.LoadLibrary('./bin/main.dll')
lib.zeros_3d.argtypes = [c_int, c_int, c_int]
lib.zeros_3d.restype = np.ctypeslib.ndpointer(dtype=c_int, ndim=3, shape=(3, 2, 4))
print(lib.zeros_3d(3, 2, 4))
And the generated output is:
[[[ 4490944 0 4491040 0]
[ 4491136 0 387641098 268496650]]
[[ 4490976 0 4491008 0]
[ 4456792 0 387641098 268496650]]
[[ 0 0 0 0]
[ 4456792 0 387641098 268496650]]]
While it should be 0 all over.
Please Help me fast I want to finish this project before my school opens.
I don't think its a good idea to store frames in a Multi-Dimensional array as you mentioned. It would be easier to store the data in a linear 1-D array.
int*** zeros_3d_cpp(int n1, int n2, int n3) {
int ***arr = new int**[n1];
for (int i = 0; i < n1; i++) {
arr[i] = new int*[n2];
for (int j = 0; j < n2; j++) {
arr[i][j] = new int[n3];
for (int k = 0; k < n3; k++) {
arr[i][j][k] = 0;
}
}
}
return arr;
}
I would split the code into 2 parts, first allocating Array and then fill it up.
int* zeros_3d_cpp(int width, int height, int breadth) {
//Allocating Memory
int *arr = new int[width*height*breadth];
for (int i = 0; i < breadth; i++)
{
//Iterates over 2D Image
for (int j = 0; j < height; j++)
{
//Iterates over a Single Row
for (int k = 0; k < width; k++)
{
arr[i*width*height + j*width +k] = 0;
}
}
}
return arr;
}
Make sure to bind the memory (ie) the returned array ptr to some object in python.
Memory
Also you are using Raw Pointers, use extra precaution to see who is managing the memory of the resource. You can allocate the memory (Dynamic Array in your case) from python side using numpy or allocate from C++ and track the object lifetime in Python to make sure it's freed correctly.
You can also create the array in python using numpy and then return the pointer into C++ and so your C++ function would take the starting pointer address as input
void zeros_3d_cpp(int* start_address, int width, int height, int breadth) {
//Only fill in with zeros
}

maximum of gcd of huge list of number [duplicate]

what is the fastest way to compute the greatest common divisor of n numbers?
Without recursion:
int result = numbers[0];
for(int i = 1; i < numbers.length; i++){
result = gcd(result, numbers[i]);
}
return result;
For very large arrays, it might be faster to use the fork-join pattern, where you split your array and calculate gcds in parallel. Here is some pseudocode:
int calculateGCD(int[] numbers){
if(numbers.length <= 2){
return gcd(numbers);
}
else {
INVOKE-IN-PARALLEL {
left = calculateGCD(extractLeftHalf(numbers));
right = calculateGCD(extractRightHalf(numbers));
}
return gcd(left,right);
}
}
You may want to sort the numbers first and compute the gcd recursively starting from the smallest two numbers.
C++17
I have written this function for calculating gcd of n numbers by using C++'s inbuilt __gcd(int a, int b) function.
int gcd(vector<int> vec, int vsize)
{
int gcd = vec[0];
for (int i = 1; i < vsize; i++)
{
gcd = __gcd(gcd, vec[i]);
}
return gcd;
}
To know more about this function visit this link .
Also refer to Dijkstra's GCD algorithm from the following link. It works without division. So it could be slightly faster (Please correct me if I am wrong.)
You should use Lehmer's GCD algorithm.
How about the following using Euclidean algorithm by subtraction:
function getGCD(arr){
let min = Math.min(...arr);
let max= Math.max(...arr);
if(min==max){
return min;
}else{
for(let i in arr){
if(arr[i]>min){
arr[i]=arr[i]-min;
}
}
return getGCD(arr);
}
}
console.log(getGCD([2,3,4,5,6]))
The above implementation takes O(n^2) time. There are improvements that can be implemented but I didn't get around trying these out for n numbers.
If you have a lot of small numbers, factorization may be actually faster.
//Java
int[] array = {60, 90, 45};
int gcd = 1;
outer: for (int d = 2; true; d += 1 + (d % 2)) {
boolean any = false;
do {
boolean all = true;
any = false;
boolean ready = true;
for (int i = 0; i < array.length; i++) {
ready &= (array[i] == 1);
if (array[i] % d == 0) {
any = true;
array[i] /= d;
} else all = false;
}
if (all) gcd *= d;
if (ready) break outer;
} while (any);
}
System.out.println(gcd);
(works for some examples, but not really tested)
Use the Euclidean algorithm :
function gcd(a, b)
while b ≠ 0
t := b;
b := a mod b;
a := t;
return a;
You apply it for the first two numbers, then the result with the third number, etc... :
read(a);
read(b);
result := gcd(a, b);
i := 3;
while(i <= n){
read(a)
result := gcd(result, a);
}
print(result);
Here below is the source code of the C program to find HCF of N numbers using Arrays.
#include<stdio.h>
int main()
{
int n,i,gcd;
printf("Enter how many no.s u want to find gcd : ");
scanf("%d",&n);
int arr[n];
printf("\nEnter your numbers below :- \n ");
for(i=0;i<n;i++)
{
printf("\nEnter your %d number = ",i+1);
scanf("%d",&arr[i]);
}
gcd=arr[0];
int j=1;
while(j<n)
{
if(arr[j]%gcd==0)
{
j++;
}
else
{
gcd=arr[j]%gcd;
i++;
}
}
printf("\nGCD of k no.s = %d ",gcd);
return 0;
}
For more refer to this website for further clarification.......
You can use divide and conquer. To calculate gcdN([]), you divide the list into first half and second half. if it only has one num for each list. you calculate using gcd2(n1, n2).
I just wrote a quick sample code. (assuming all num in the list are positive Ints)
def gcdN(nums):
n = len(nums)
if n == 0: return "ERROR"
if n == 1: return nums[0]
if n >= 2: return gcd2(gcdN(nums[:n//2]), gcdN(nums[n//2:]))
def gcd2(n1, n2):
for num in xrange(min(n1, n2), 0, -1):
if n1 % num == 0 and n2 % num == 0:
return num
Here's a gcd method that uses the property that gcd(a, b, c) = gcd(a, gcd(b, c)).
It uses BigInteger's gcd method since it is already optimized.
public static BigInteger gcd(BigInteger[] parts){
BigInteger gcd = parts[0];
for(int i = 1; i < parts.length; i++)
gcd = parts[i].gcd(gcd);
return gcd;
}
//Recursive solution to get the GCD of Two Numbers
long long int gcd(long long int a,long long int b)<br>
{
return b==0 ? a : gcd(b,a%b);
}
int main(){
long long int a,b;
cin>>a>>b;
if(a>b) cout<<gcd(a,b);
else cout<<gcd(b,a);
return 0;
}
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
class GCDArray{
public static int [] extractLeftHalf(int [] numbers)
{
int l =numbers.length/2;
int arr[] = Arrays.copyOf(numbers, l+1);
return arr;
}
public static int [] extractRightHalf(int [] numbers)
{
int l =numbers.length/2;
int arr[] = Arrays.copyOfRange(numbers,l+1, numbers.length);
return arr;
}
public static int gcd(int[] numbers)
{
if(numbers.length==1)
return numbers[0];
else {
int x = numbers[0];
int y = numbers[1];
while(y%x!=0)
{
int rem = y%x;
y = x;
x = rem;
}
return x;
}
}
public static int gcd(int x,int y)
{
while(y%x!=0)
{
int rem = y%x;
y = x;
x = rem;
}
return x;
}
public static int calculateGCD(int[] numbers){
if(numbers.length <= 2){
return gcd(numbers);
}
else {
int left = calculateGCD(extractLeftHalf(numbers));
int right = calculateGCD(extractRightHalf(numbers));
return gcd(left,right);
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int arr[] = new int[n];
for(int i=0;i<n;i++){
arr[i]=sc.nextInt();
}
System.out.println(calculateGCD(arr));
}
}
**
Above is the java working code ..... the pseudo code of which is
already mention by https://stackoverflow.com/users/7412/dogbane
**
A recursive JavaScript (ES6) one-liner for any number of digits.
const gcd = (a, b, ...c) => b ? gcd(b, a % b, ...c) : c.length ? gcd(a, ...c) : Math.abs(a);
This is what comes off the top of my head in Javascript.
function calculateGCD(arrSize, arr) {
if(!arrSize)
return 0;
var n = Math.min(...arr);
for (let i = n; i > 0; i--) {
let j = 0;
while(j < arrSize) {
if(arr[j] % i === 0) {
j++;
}else {
break;
}
if(j === arrSize) {
return i;
}
}
}
}
console.log(generalizedGCD(4, [2, 6, 4, 8]));
// Output => 2
Here was the answer I was looking for.
The best way to find the gcd of n numbers is indeed using recursion.ie gcd(a,b,c)=gcd(gcd(a,b),c). But I was getting timeouts in certain programs when I did this.
The optimization that was needed here was that the recursion should be solved using fast matrix multiplication algorithm.

Evaluating C function on a numpy grid using Cython

The example in Simple wrapping of C code with cython describes nicely how to evaluate a function written in C on an array passed from numpy and return the result in a numpy array.
How would one go about doing the same thing but returning a 2D array? I.e. I'd like to evaluate a C function on a grid defined by two numpy arrays, and return the result as a numpy 2D array.
It would be something like this (using same functions as in the link above). Obviously one can't use double z[] now, but I'm not sure how to pass a 2D numpy array to C.
/* fc.cpp */
int fc( int N, const double a[], const double b[], double z[] )
{
for( int i = 0; i < N; i ++ ){
for( int j = 0; j < N; j ++ ){
z[i][j] = somefunction(a[i],b[j]);
}
return N;
}
This is the original .pyx file (see below).
import numpy as np
cimport numpy as np
cdef extern from "fc.h":
int fc( int N, double* a, double* b, double* z ) # z = a + b
def fpy( N,
np.ndarray[np.double_t,ndim=1] A,
np.ndarray[np.double_t,ndim=1] B,
np.ndarray[np.double_t,ndim=1] Z ):
""" wrap np arrays to fc( a.data ... ) """
assert N <= len(A) == len(B) == len(Z)
fcret = fc( N, <double*> A.data, <double*> B.data, <double*> Z.data )
return fcret
Many thanks.
You can use a normal array for a 2D Matrix. You need only give the length of the dimension to the function.
In the C file do something as that:
(z is now an array of length N*N)
int fc( int N, const double a[], const double b[], double z[] )
{
for( int i = 0; i < N; i++ ){
for( int j = 0; j < N; j ++ ){
z[(i*N)+j] = somefunction(a[i],b[j]);
}
return N;
}
In Python you need to do the same, so you can use a 1D Array with N*N elements instead of an 2D Matrix.
Update 3D case
(z is now an array of length N*N*N)
int fc( int N, const double a[], const double b[],const double c[], double z[] )
{
for( int i = 0; i < N; i++ ){
for( int j = 0; j < N; j ++ ){
for( int k = 0; k < N; k ++ ){
z[((i*N)+j)*N+k] = somefunction(a[i],b[j],c[k]);
}
return N;
}

Categories