'Output problem when I called 2d array functions from python 3
I am a newbie at coding. My sysyem is win10 64 bit. I'm using CodeBlocks to write C code. Also I'm using Python 3.10. This is my C code. This function adds the value 0.99 to all elements of a matrix. I want to call this function from python 3. My C file is;
cab2.c
#include <stdio.h>
#include <stdlib.h>
c_bes(const int ** s, int R) {
float** nrm=(float**)malloc(R*sizeof(int*));
for (int i = 0; i < R; i++){
nrm[i]=(float*)malloc(sizeof(int)*R);
}
for( int i=0; i<R; i++){
for(int j=0; j<3; j++){
nrm[i][j]= 0.9;
}
}
return nrm;
}
it works and adding the 0.9 value an n*m zero matrix successfully in C . As mentioned above in order to use this function with python,I compiled this code with this command and I written python code as below.
gcc -o c_bes.so --shared -fPIC cab2.c
my python code;
Test.py
from ctypes import c_void_p, c_double, c_int, cdll, c_float
from numpy.ctypeslib import ndpointer
import numpy as np
row=2
col=3
orn = np.matrix([[0, 0, 0],
[0, 0, 0]])
print (orn)
lib = cdll.LoadLibrary("C:/Users/Casper/Desktop/Cfunc_in_pyt_2/c_bes.so")
c_bes = lib.c_bes
c_bes.restype = ndpointer(dtype=c_float, shape=(row,col))
res = c_bes( c_void_p(orn.ctypes.data), c_int(row) )
print(res)
my output is;
[[0 0 0]
[0 0 0]]
[[-2.8212709e-34 8.6600245e-43 -2.8212783e-34]
[ 8.6600245e-43 0.0000000e+00 0.0000000e+00]]
As shown above this give me wrong output! All matrix element must be 0.9 ! What is my wrong? Despite all my efforts, I can't succeed! Please help me.
Solution 1:[1]
Requirements: With a C-function, 0.99 is to be added to all elements of a matrix. The matrix is to come from Python.
There are a couple of problems:
- the argument
sin the C function seems to be the intended Python matrix, but the parameter is not used at all in the C function. - the type for
sis wrong, assuming a contiguous array it should just befloat * c_beshas no declared return type, you could usevoidsince the matrix elements can be manipulated in-place- if you would prefer dynamically allocated memory on the C side after all, you should use the correct sizes, so if you want to work with a float array, you should not use
sizeof(int)butsizeof(float). - if dynamic memory is used, you should also free it after use
- maybe use better naming to make the code more readable, e.g. something like
matrix,cols,rowsetc - with the compiler options
-Wall -Wextrayou get helpful warnings about possible problems in the code, use these = 0.9assigns a fixed value, but actually you want to add something to the matrix element, so use the addition assignment+= 0.99f. Thefat the end indicates that you want to work with a float constant and not a double constant- in Python, the types of function arguments can be described using
argtypes - with
dtypethe desired type of the matrix elements can be specified
If you apply the points just listed to your example code, it might look something like this:
cab2.h:
#ifndef C_BES_LIBRARY_H
#define C_BES_LIBRARY_H
void c_bes(float *input, int rows, int cols);
#endif //C_BES_LIBRARY_H
cab2.c:
#include "cab2.h"
void c_bes(float *matrix, int rows, int cols) {
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
matrix[r * cols + c] += 0.99f;
}
}
}
Python
from ctypes import c_int, cdll, c_float
from numpy.ctypeslib import ndpointer
import numpy as np
rows = 2
cols = 3
lib = cdll.LoadLibrary("C:/Users/Casper/Desktop/Cfunc_in_pyt_2/c_bes.so")
c_bes = lib.c_bes
c_bes.argtypes = [ndpointer(c_float, flags="C_CONTIGUOUS", shape=(rows, cols)), c_int, c_int]
orn = np.matrix([[1, 2, 3],
[4, 5, 6]], dtype=np.float32)
c_bes(orn, rows, cols)
print(orn)
Test
The above code then outputs the following on the debug console:
[[1.99 2.99 3.99]
[4.99 5.99 6.99]]
Note that I have changed the input matrix so that it can be seen that the correct operations are performed on the values of the input matrix.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Stephan Schlecht |
