Using GSL lib functions on data in a struct C - c

Many GSl functions take arguments as doubles or arrays of doubles. However much of my data is nested in arrays of structs instead. Say like arrays of:
struct A
{
double a;
int b;
};
I could write a wrapper that copies the data into an array of pure doubles or ints. But I was interested in something more elegant to get around this.

Not the answer you want. But since you cant change the GSL interface, if you are looking for performance, I think your best solution is probably to chose data structures that matches the job from the start. So maybe something like a struct containing arrays of doubles.
If both the GSL interface and your original data structure is out of your control, then your only option is probably going to be the wrapper that you are thinking about.
If the library functions that you are using could take a 'stride' argument, you could possibly look into structure packing and padding. (But that still wouldn't convert your ints to doubles.)

"...much of my data is nested in arrays of structs instead. ... I
could write a wrapper that copies the data into an array of pure
doubles or ints. But I was interested in something more elegant to get
around this."
There is no need to write a wrapper to copy the data into an an array of pure double or int. The fact that you have an array-of-struct already provides convenient direct access to every stored value. With an array-of-struct accessing each individual struct within the array is a simple matter of indexing the struct you want, e.g. array[n] where n is the wanted element within the array.
In your example array[n].a provides direct access to the double value in member a and array[n].b provides direct access to the int member b for each of the valid index within your array.
A short example of this indexing for direct access to each member of each struct within the array may help. The following initializes array with five struct with the double and int values shown. The int values are then incremented by 1 within the loop before each member of each struct is output, e.g.
#include <stdio.h>
typedef struct A { /* struct A (with a typedef for convenience) */
double a;
int b;
} A;
int main (void) {
/* array of struct A */
A array[] = {{1.1, 1}, {2.2, 2}, {3.3, 3}, {4.4, 4}, {5.5, 5}};
size_t nelem = sizeof array / sizeof *array; /* no. elements */
for (size_t i = 0; i < nelem; i++) {
array[i].b++; /* increment int/output stored values */
printf ("array[%zu]: {%3.1f, %d}\n", i, array[i].a, array[i].b);
}
}
Example Use/Output
Note how the integer value stored within each struc in the array-of-struct is incremented by 1 before the values in each struct with the array is directly used as the parameter being output by printf:
$ ./bin/arraystruct
array[0]: {1.1, 2}
array[1]: {2.2, 3}
array[2]: {3.3, 4}
array[3]: {4.4, 5}
array[4]: {5.5, 6}
Your access of each member regardless how you want to use it would be the same. Look things over and let me know if you have further questions.

Related

How to assign 1D array to a 2D array?

I have a 1D array A[3] & a 2D array B[4][3]. I want to assign the array A[3] to one of the rows of array B[4][3]. How to do it correctly?
#include<stdio.h>
void main()
{
int A[3]={1,2,3};
int B[4][3]={0};
int row_select=2;
B[row_select][] = A;
}
But this assignment doesn't work. I don't want to assign element by element using a for loop. I want to do it in one statement.
memcpy could be a good option, although it's very likely it uses a loop internally.
memcpy(B[row_select], A, sizeof(A));
Don't Do This: Use memcpy
There is a way to do the assignment with a single statement, as long as you are willing to do some preliminary setup to render your code illegible. Your can use the fact that structures can (1) be assigned to each other in one step, and (2) contain fixed-size arrays. The compiler will probably run memcpy under the hood anyway, but it's a fun exercise in ridiculousness:
#include<stdio.h>
#define SZ 3 // this is just for convenience
// a pointer to an anonymous structure containing our array
typedef struct {
int x[SZ];
} *pthrowaway;
int main(void)
{
int A[SZ]={1,2,3};
int B[4][SZ]={0};
int row_select=2;
pthrowaway a = (pthrowaway)&A;
pthrowaway b = (pthrowaway)&B[row_select];
*b = *a; // magic
return 0;
}
The variables a and b are unnecessary. You can actually assign the arrays in a single statement:
*(pthrowaway)&B[row_select] = *(pthrowaway)&A;
Here is an IDEOne link showing the C99 version: https://ideone.com/IQ6ttg
And here is a regular C one: https://ideone.com/pH1hS2

Structure wrapper and variable array size

I often use :
Array wrappers to pass array by value but the problem is that the size of array is determined at compile time (see part I of the code)Array declarations that depend of a variable (see part II of the code)
How is it possible to "combine" these two types of code to have array wrappers that depends of a variable ? (see part III of the code. I know it can not work because there is a variable in structure declaration, it is just here to give an idea)
#include <stdio.h>
int main() {
// First part of code
// Array wrapper to pass array by value but size of array is determined at compile time
struct S {int m_array[5];} myarray={1,2,3,4,5};
struct S myarraycopy;
struct S copyarray(struct S a) { return a ;}
myarraycopy=copyarray(myarray);
for (int i=0;i<5;i++) printf("%d \n",myarraycopy.m_array[i]);
// Second part of code
// Array declaration is function of a variable n and
// so it is not determined at compile time
int n;
printf("Size : ");scanf("%d",&n);
int myarray1[n];
for (int i=0;i<n;i++) myarray1[i]=i;
printf("Array size %d \n",sizeof(myarray1));
for (int i=0;i<n;i++) printf("%d \n",myarray1[i]);
/* How to combine the two parts above ???
int n1;
printf("Size : ");scanf("%d",&n1);
struct S1 {int m_array[n1];} myarray1;
struct S1 myarraycopy1;
struct S1 copyarray1(struct S1 a) { return a ;}
myarraycopy1=copyarray1(myarray1);*/
}
How is it possible to "combine" these two types of code to have array wrappers that depends of a variable ?
You cannot, at least in standard C. In the standard's terms, the members of a structure type cannot be variably-modified. This serves the purpose that the size of a structure type is always a compile-time constant (even, technically, structure types having flexible array members).
In the general case, you have the alternative of passing your array normally, in the form of a pointer to its first element. You may declare the function parameter as a pointer to const elements, so that the function cannot modify the array (at least, not without casting away the constness, which you could surely persuade your compiler to warn about).
That does not serve your copyarray() use case, because you cannot return arrays (as such) either, nor assign to whole arrays. But memcpy() does that job fine without need for wrapping or passing around arrays by value, so the case seems contrived.
I try to use flexible array member (see code below). I am not surprised that this code does not work. Indeed, the size of the flexible array is not know at compile time (cf standard 6.7.2.1 *s1=*s2;). But, as the size of myarray1 is known ( sizeof(S1)+n1*sizeof(int) ), I wonder if Inline Assembly Language in the code could be used to force the copy of the whole variable myarray1.
#include <stdio.h>
typedef struct {int l;int m_array[];}S1;
void myfoo(S1 a) {
for (int i=0;i<a.l;i++) a.m_array[i]*=10;
printf("in myfoo\n");
for (int i=0;i<a.l;i++) printf("%d \n",a.m_array[i]);
}
int main() {
int n1;
printf("Size : ");scanf("%d",&n1);
S1 *myarray1=malloc(sizeof(S1)+n1*sizeof(int));
myarray1->l=n1;
for (int i=0;i<n1;i++) myarray1->m_array[i]=i;
myfoo(*myarray1);
printf("in main\n");
for (int i=0;i<n1;i++) printf("%d \n",myarray1->m_array[i]);
}

How to pass lists into a ctypes function on python

This is a 2 part question. To give some background, I have a C code as follows:
int c_func(const char* dir, float a, float b, float c, float d )
{
printf("%s\n", dir);
printf("%f\n",a);
printf("%f\n",b);
printf("%f\n",c);
printf("%f\n",d);
return 0;
}
This is a simple function that takes in a string and 4 floats as arguments and prints them out I am trying to test my phython/C interface. My python code is as follows:
calling_function = ctypes.CDLL("/home/ruven/Documents/Sonar/C interface/Interface.so")
calling_function.c_func("hello",1, 2, 3, 4])
Now since this works, instead of passing 4 individual floats, I would like to pass in a list of 4 floats. I have tried different code online to edit my C function so that it takes in a list as one of its parameters but I cant seem to figure out how to do so as I am a new programmer and I am not experienced with C.
Question 1: How do I code a C function to accept a list as its arguments?
Question 2: This list of four floats is actually coming from a list of lists from my python code. After coding the C function would I be able to use a numpy array called testfv2[0,:] as an input of the C function?testfv2[0,:]is a list of dimensions 1x4 and testfv2 is a list of dimensions 117x4. For now, I would like to into the C function 1 row at a time which is why I thought using testfv2[0,:].
How do I code a C function to accept a list as its arguments?
Short answer, you can't.
Long answer: C does not have lists, but has arrays and pointers.
You have several options then:
int c_func(const char *dir, float abcd[4]) { // using an array with explicit size
int c_func(const char *dir, float abcd[]) { // Using an array (will decay to a pointer at compile-time)
int c_func(const char *dir, float *abcd) { // Using a pointer.
If you will only ever receive 4 floats, I'd suggest the first form, which enforces the size of the array, any user (and mainly your future self) of your function will know to give only an array of four elements.
Calling your function from Python:
floats = [1.0, 2.0, 3.0, 4.0] # Or whatever values you want to pass, but be sure to give only 4
FloatArray4 = ctypes.c_float * 4 # Define a 4-length array of floats
parameter_array = FloatArray4(*floats) # Define the actual array to pass to your C function
I don't know if passing more than 4 floats to FloatArray4 raises an error -- I guess so, but I can't check right now.
As for your second question, if you want dynamic sized arrays (more than 4 elements), you'll have to you one of the other two profiles for your C function, in which case I advise you to put an extra int argument for the size of the array:
int c_func(const char *dir, float floats[], int size) {
or
int c_func(const char *dir, float *floats, int size) {
You can also use the standard size_t instead of int, it's designed just for that.
I you want to pass a multidimensional array, you add another pair of brackets:
int c_func(const char *dir, float floats[][4]) { // Note the explicit size for second dimension
but remember that for a C array, for all dimensions but the first, the dimensions must be explicitly specified. If the value is constant it wont be an issue, however if not you will have to use a pointer instead:
int c_func(const char *dir, float *floats[]) {
or
int c_func(const char *dir, float **floats) {
which are two identical syntaxs (the array will decay to a pointer). Once again, if your dimensions are dynamic, I suggest to add parameters for the size.
If you want supplementary dimensions, just repeat that last step.

How do I pass a multi-dimensional array of variable size in C?

I'm trying to pass an three dimensional array to a function like this:
void example( double*** bar ) {
// Stuff
}
int main() {
double[3][2][3] foo;
// Initialize foo
example( foo );
return 0;
}
This causes the gcc to give me "Invalid pointer type". How am I supposed to be doing this? I could just make the entire argument a one-dimensional array and arrange my data to fit with that, but is there a more elegant solution to this?
edit:
In addition, I can't always specify the length of each sub-array, because they may be different sizes. e.g.:
int* foo[] = { { 3, 2, 1 }, { 2, 1 }, { 1 } };
If it helps at all, I'm trying to batch pass inputs for Neurons in a Neural Network. Each Neuron has a different number of inputs.
just use double*. A multidimensional array is stored contiguously in memory so you are quite welcome to give it your own stride. This is how bitmaps are passed on OpenGL.
A one-dimensional int array decays into an int pointer when passing it to a function. A multi-dimensional array decays into a pointer to an array of the next lowest dimension, which is
void example(double (*bar)[2][3]);
This syntax can be a bit baffling, so you might chose the equivalent syntax:
void example(double bar[][2][3]) {
// Stuff
}
int main() {
double foo[3][2][3];
example(foo);
return 0;
}
The first dimension does not have to be given, it's that part that is "decaying". (Note that the dimensions of arrays are not given on the type as in Java, but on the array name.)
This syntax works for variable-length arrays (VLAs) as well, as long as you pass the dimensions before the array:
void example(int x, int y, double (*bar)[x][y]) {
// Stuff
}
int main() {
double foo[3][2][3];
example(2, 3, foo);
return 0;
}
This feature requires C99 and is not compatible with C++.
If the array size is fixed, you can use:
void example(double bar[][2][3]) {
}
Otherwise, you can pass the size along with the array into the function:
void example(size_t x, size_t y, size_t z, double bar[x][y][z]) {
}
That can't be done in C the way you're thinking of. If you need a function that operates on variable-size multidimensional arrays, you'll either have to pass the sizes (all but one) explicitly to the function, or make a structure and pass that. I generally always make a structure when a 2D or 3D array is called for, even if they're of fixed size. I think it's just cleaner that way, since the structure documents itself.

C existing pointer to fixed-size array

Let's say that any C function has a pointer already declared, but not assigned any value yet. We will int for our examples.
int *ptr;
The goal of the function is not to assign ptr any dynamic memory on the heap, so no malloc call. Instead, we want to have it point to an array of fixed size n. I know I could accomplish this like so:
int arr[n];
ptr = arr;
However, the code could get very messy and hard to read if we need to do this many times in a function, ie, a struct of many pointer fields all need to point to an array of fixed length. Is there a better way to accomplish this in one line? I was thinking of something similar to below, but it looks too ambiguous and uncompilable:
int *ptr;
// Many other things happen in between...
ptr[n];
***EDIT***
Here, the below additional information may help guide some more answers (not saying that the current answers are not fine). In my use case, the pointers are declared in a struct and, in a function, I am assigning the pointers to an array. I want to know if there is a simpler way to accomplish this than in the below code (all pointers to point to fixed-length array):
struct foo {
int* a;
short* b;
char* c;
...
};
void func(void) {
struct foo f;
int n = ...;
int tempArr1[n];
f.a = tempArr1;
short tempArr2[n];
f.b = tempArr2;
char tempArr3[n];
f.c = tempArr3;
...
}
You cannot declare an array and assign it to an existing pointer in a single declaration. However, you can assign an array pointer to a newly declared pointer, like this:
int arr[n], *ptr = arr;
If you insist on staying within a single line, you could use an ugly macro, like this:
#define DECL_ASSIGN_INT_ARRAY(name,size,pointer) int name[(size)]; pointer = name;
The clarity of this one-liner is far lower than that of a two-line version from your post, so I would keep your initial version.
EDIT (in response to the edit of the question)
Another option is to create an unused pointer variable in a declaration, and assign your pointer in an initializer, like this:
void func(void) {
struct foo f;
int n = ...;
int tempArr1[n], *tempPtr1 = f.a = tempArr1;
short tempArr2[n], *tempPtr2 = f.b = tempArr2;
char tempArr3[n], *tempPtr3 = f.c = tempArr3;
...
}
This seems like a clear case where you're in need of some refactoring. Take the similar statements, extract them into a new function (by passing a reference to the struct and the data you want the struct fields to point to) and give this new function a meaningful name.
This is probably more maintainable and readable than some fancy pointer arithmetic shortcut that you'll forget about in a few weeks or months.
The difference between ptr and arr in you example is you can change ptr's value. So I guess you want to move ptr through the array.
So how about this:
int arr[n], id=0;
And you change the value of id and use arr+id as ptr.
I guess the way to do this is to use a macro. Something like (untested)
#define autoptr(name,size) int Arrayname[size]; name = Arrayname;
I'm not clear why this is helping I think it might "look ugly" but will be easier to maintain without the macro. In general, hiding what you are actually doing is a bad thing.

Resources