manage array of memory directions - c

I have several variables inside a struct.
struct my_struct{
float variable_2_x[2],variable_2_y[2],variable_2_z[2];
float coef_2_xyz[3];
float variable_3_x[3],variable_3_y[3],variable_3_z[3];
float coef_3_xyz[3];
float variable_4_x[4],variable_4_y[4],variable_4_z[4];
float coef_4_xyz[3];
};
This struct its going to contain Lagrange polynomial (en.wikipedia.org/wiki/Lagrange_polynomial) coefficients, for several polynomial lenght: 2, 3, 4. The value of this coefficients its easy to calculate but the problem is, that i have to repeat the same code to create every single polynomial. for example
// T_space is a cube with {[-1:1][-1:1][-1:1]} dimension,
// its call transformed space.
// distance is the distance between two points of T_space
// point_1 its the point where the function has value 1
p = 2;
step = distance / p;
polinoms.coef_2_xyz[0] = 1.0:
polinoms.coef_2_xyz[1] = 1.0:
polinoms.coef_2_xyz[2] = 1.0:
for( i = 0; i < p ; ++i)
{
polinoms.pol_2_x[i] = (T_space.xi[point_1] + step) + (i * step);
polinoms.pol_2_y[i] = (T_space.eta[point_1] + step) + (i * step);
polinoms.pol_2_z[i] = (T_space.sigma[point_1] + step) + (i * step);
polinoms.coef_2_xyz[0]*= (T_space.eta[point_1] - polinoms.pol_2_x[i]);
polinoms.coef_2_xyz[1]*= (T_space.eta[point_1] - polinoms.pol_2_y[i]);
polinoms.coef_2_xyz[2]*= (T_space.eta[point_1] - polinoms.pol_2_z[i]);
}
As i don't want to repeat the same loop several times in the code. And what is more important next step in the code i need to integrate the product of the gradient of the polynomial, to every point in the cube.
It will very useful beening able to call every array of the struct independently.
As i know that, variables can't be dynamically called on runtime. I think of making an array which contains the memory directions of the struct. something like this.
// declare variable to store memory directions
float mem_array[12];
// some code
mem_array[0] = &variable_2_x;
mem_array[1] = &variable_2_y;
mem_array[2] = &variable_2_z;
mem_array[3] = &coef_2_xyz;
mem_array[4] = &variable_3_x;
mem_array[11] = &variable_4_z;
mem_array[12] = &coef_4_xyz;
// work calling mem_array.
But i don't know if this is possible or if it will work. If you think this is not the proper way to face the problem, i'm open to advice. Because i'm really stuck with this.
I have edited the question to be more clear, hope it will help.

You'd be better to allocate the memory you need dynamically. You can have a struct that represents a single Lagrange polynomial (of any order), and then have an array of these, one for each order.
You could also store the order of the polynomial as a member of the struct if you wish. You should be able to factor out code that deals with these into functions that take a LagrangePolynomial*, determine the order, and do whatever computation is required.
The key benefit of all of this is that you don't need to have special code for each order, you can use the same code (and the same struct) for any size of polynomial.
Example below:
struct LagrangePolynomial {
float *x;
float *y;
float *z;
};
For p=2:
LagrangePolynomial p;
p.x = malloc(sizeof(float)*2);
p.y = malloc(sizeof(float)*2);
p.z = malloc(sizeof(float)*2);
for (size_t i=0; i<2; i++) {
p.x[i] = ...;
p.y[i] = ...;
p.z[i] = ...;
}
When you've finished with the structure you can free all the memory you've allocated.
free(p.x);
free(p.y);
free(p.z);
As mentioned before you can have an array of these.
LagrangePolynomial ps[4];
for (size_t i=0; i<4; i++) {
p[i].x = malloc(sizeof(float)*2);
p[i].y = malloc(sizeof(float)*2);
p[i].z = malloc(sizeof(float)*2);
for (size_t j=0; j<2; j++) {
p[i].x[j] = ...;
p[i].y[j] = ...;
p[i].z[j] = ...;
}
}

Related

knn implementation in 3d space for n closest neighbours

I am newbie to c. I have n structs holding the 4 members, 1st the unique index of and three floats representing special coordinates in 3D space. I need to find k nearest struct according to Euclidian distances.
//struct for input csv data
struct oxygen_coordinates
{
unsigned int index; //index of an atom
//x,y and z coordinates of atom
float x;
float y;
float z;
};
struct oxygen_coordinates atom_data[n];
//I need to write a function something like,
knn(atom_data[i], atom_data, k); // This should return to 4 closest struct based on Euclidian distances.
//I have already written a function to get distances.
//Distance function for two pints in a struct
float getDistance(struct oxygen_coordinates a, struct oxygen_coordinates b)
{
float distance;
distance = sqrt((a.x - b.x) * (a.x - b.x) + (a.y-b.y) *(a.y-b.y) + (a.z - b.z) * (a.z - b.z));
return distance;
}
At this point I am totally lost, any leads on algorithm will be really helpful. Particularly, in my data set there are only 3d coordinates therefore do I really need to classify points ? Thank you in advance.
Here is some code that might help you. This code is just to give an idea about the approach to the problem, as asked in the question.
// declare a global array that will hold the 4 nearest atom_data...
struct oxygen_coordinates nearestNeighbours[4];
// This function adds the structure passed to it until it becomes full, after that it replaces the structure added from the first...
void addStructure(struct oxygen_coordinates possibleNeighbour) {
static int counter = 0;
int length = sizeof(nearestNeighbour)/sizeof(possibleNeighbour);
if(length < 3) {
nearestNeighbours[length] = possibleNeighbour;
}
else {
nearestNeighbours[counter%4] = possibleNeighbour;
counter++;
}
}
Given atom is the atom_data of the atom you want to find the neighbours of and atom data is the whole array.
Now we make a new float variable which stores the min distance found so far, and initialize it with a very high value.
After that we loop through the atom_data and if we find a candidate with distance less than the min value we have stored, we update the min value and add the structure to our nearestNeighbours array via the add method we created above.
Once we loop through the entire structure, we will have the 4 nearest atom_data inside the nearestNeighbour array.
knn(given_atom, atom_data, k) {
float minDistance = 10000; // Some large value...
for(int i=0; i<n; i++) {
int tempDistance = getDistance(given_atom, atom_data[i])
if(tempDistance<minDistance) {
addStructure(atom_data[i])
}
}
}
The time complexity will depend on the length of the atom_data, i.e. n. If the array is stored in a sorted manner, this time complexity can be reduced significantly.
You may want to use a spatial index, such as the boost R-Tree. There are others, but this is the only one that comes with boost, as far as I am aware.
Other (much simpler) spatial indexes are quadtrees and kD-trees.

Reshaping an array from 1D to ND in C

I am having a lot of trouble trying to implement this on my own, so if anyone can point to, or describe an algorithm I'd be much obliged.
The problem statement
Given one dimensional flattened pointer int* i which would look something like this {1,2,3,4}, and given a list of dimensions in form of a list {2,2} reshape the 1D array to conform with specified dimensions. Overall after the procedure the array should look like {{1,2},{3,4}}.
I am basically asking if anyone knows the algorithm that is used in numpy.reshape.
A n-dimensional array in c is nothing more than syntactic sugar for computing the offset inside a simple array, they look the same in memory (one contiguous block). Therefore, there's really no point in "reshaping" it, as this little sample demonstrates:
#include <stdio.h>
int data[] = {1,2,3,4};
int main(void)
{
int *i = data;
for (int n = 0; n < 4; ++n)
{
printf("i[%d] = %d\n", n, i[n]);
}
int (*j)[2] = (void *)i;
for (int n1 = 0; n1 < 2; ++n1)
{
for (int n2 = 0; n2 < 2; ++n2)
{
printf("j[%d][%d] = %d\n", n1, n2, j[n1][n2]);
}
}
return 0;
}
output:
i[0] = 1
i[1] = 2
i[2] = 3
i[3] = 4
j[0][0] = 1
j[0][1] = 2
j[1][0] = 3
j[1][1] = 4
NumPy doesn't need an algorithm, because it stores data contiguously regardless of the shape. The "shape" property is the only difference between the input and the output of reshape(). The algorithms come into play when later accessing the array, such as when printing it. Then you need to follow the shape to know how many elements go in each row or other dimension.

Ruby C API - From ruby array to C array

I am passing an array (matrix) from Ruby to a C function. At the moment I am using the following code
VALUE matmat_mul(VALUE self, VALUE matrixA, VALUE matrixB)
{
int rowsA = RARRAY_LEN(matrixA);
VALUE firstElement = rb_ary_entry(matrixA, 0);
int colsA = RARRAY_LEN(firstElement);
int rowsB = RARRAY_LEN(matrixB);
firstElement = rb_ary_entry(matrixB, 0);
int colsB = RARRAY_LEN(firstElement);
int i,j;
double *matA = (double *)malloc(rowsA * colsA * sizeof(double));
double *matB = (double *)malloc(rowsB * colsB * sizeof(double));
VALUE rowA;
for (i=0; i<rowsA; i++)
{
rowA = rb_ary_entry(matrixA, i);
for (j=0; j<colsA; j++)
{
matA[i * colsA + j] = NUM2DBL(rb_ary_entry( rowA, j));
}
}
// same for matrix B
....
....
// Perform operation C = A x B
VALUE matrixC = rb_ary_new2(rowsC);
VALUE rowC;
for (i=0; i<rowsC; i++) {
rowC = rb_ary_new2(colsC);
for (j=0; j<colsC; j++) {
rb_ary_store(rowC, j, DBL2NUM(matC[i * colsC + j]));
}
rb_ary_store(matrixC, i, rowC);
}
return matrixC
}
Is there a better/quicker way to convert a Ruby array to a C array and viceversa?
No there is not a quicker way to convert Ruby Array to a C structure. That's because the Ruby Array could contain a mixture of any other kind of Ruby object, many of which could not be converted to a C double
There is another option though - NArray. This is a very efficient way of dealing with numerical multi-dimensional arrays in Ruby. There is a lot less procedure converting from an NArray to C, but it is entirely different way of doing things.
Some of it is a little complex. In summary . . .
Load the narray.h library in extconf.rb
Original version of this was from fftw3 gem (I have simplified a little):
require "mkmf"
require "narray"
narray_dir = File.dirname(Gem.find_files("narray.h").first) rescue $sitearchdir
dir_config('narray', narray_dir, narray_dir)
if ( ! ( have_header("narray.h") && have_header("narray_config.h") ) )
puts "Header narray.h or narray_config.h is not found."
exit(-1)
end
create_makefile( 'my_lib_name/my_lib_name' )
Cast input NArray objects to the data type you want to work with
Here's an example instance method that can access the NArray
VALUE example_narray_param( VALUE self, VALUE rv_narray ) {
// Cast the input to the data type you want - here 32-bit ints
volatile VALUE new_narray = na_cast_object(rv_narray, NA_LINT);
// NARRAY is the C struct interface to NArray data
struct NARRAY *na_items;
// This macro is NArray's equivalent of NUM2DBL, pointing na_items
// at the data
GetNArray( new_narray, na_items );
// row now points natively to the data
int * row = (int*) na_items->ptr;
For multi-dimensional arrays like your matrix, NArray uses a single pointer with multiplier offsets, similar to your matA[i * colsA + j] - going into full detail on this would be too long, but hopefully this is enough of a start to help you decide if this is the right solution for you.
I actually use this approach a lot in some personal projects. They are MIT licensed, so feel free to look through them and copy or re-use anything. This neural network layer class might contain some useful reference code.

How to get N unique random quantities without indefinite loop?

I want to generate 5 random positions on a map. I can only come up with the code below, which uses while (1) and break:
int map[10][10];
memset(map,0,sizeof(map));
for (int i = 0; i < 5; i++) {
while (1) {
int x = RAND_FROM_TO(0, 10);
int y = RAND_FROM_TO(0, 10);
if (map[x][y]==0) {
map[x][y]=1;
break;
}
}
}
Is there any other way to do the same job without while(1), because I have been told the while(1) is very bad.
I just want to find a simple way to do it, so the efficiency of the generating random numbers is not under my consideration.
You can use a shuffle algorithm such as Fisher–Yates. I would pose a modified (truncated) version as so:
Express your XY coordinates as a single number.
Construct a list of all coordinates.
Pick one at random, mark it.
Remove that coordinate from the list (swap it with the one at the end of the list, and treat the list as 1 element shorter)
repeat with the list that no longer contains the marked coordinate.
This way, rather than choosing 5 numbers from 0-99, you choose one 0-99, 0-98, ... 0-95, which guarantees that you can complete the task with exactly 5 choices.
EDIT: Upon further consideration, step 1 is not strictly necessary, and you could use this on a system with sparse coordinates if you did it that way.
What about something like this:
// Create an array of valid indexes for both x and y.
NSMutableArray *xCoords = [NSMutableArray array];
NSMutableArray *yCoords = [NSMutableArray array];
for (int i = 0; i < 9; ++i) {
[xCoords addObject:#(i)];
[yCoords addObject:#(i)];
}
int map[10][10];
memset(map, 0, sizeof(map));
for (int i = 0; i < 5; ++i) {
// Pick a random x coordinate from the valid x coordinate list.
int rand = RAND_FROM_TO(0, [xCoords count]);
int x = [xCoords objectAtIndex:rand];
// Now remove that coordinate so it cannot be picked again.
[xCoords removeObjectAtIndex:rand];
// Repeat for y.
rand = RAND_FROM_TO(0, [yCoords count]);
int y = [yCoords objectAtIndex:rand];
[yCoords removeObjectAtIndex:rand];
assert(map[x][y] == 0);
map[x][y] = 1;
}
Note: I'm using NSMutableArray because you originally specified Objective-C as a tag.
Note 2: An array of valid indexes is not the most efficient representation. Using NSMutableIndexSet instead is left as an exercise to the reader. As is using basic C primitives if you don't / can't use NSMutableArray.
Note 3: This has a bug where if you pick, say, x = 3 the first time, no further choices will end up with x = 3, even though there will be valid choices where x = 3 but y is different. Fixing that is also left as an exercise, but this does satisfy your requirements, on the surface.

Best solution to represent Data[i,j] in c?

There is a pseudocode that I want to implement in C. But I am in doubt on how to implement a part of it. The psuedocode is:
for every pair of states qi, and qj, i<j, do
D[i,j] := 0
S[i,j] := notzero
end for
i and j, in qi and qj are subscripts.
how do I represent D[i,J] or S[i,j]. which data structure to use so that its simple and fast.
You can use something like
int length= 10;
int i =0, j= 0;
int res1[10][10] = {0, }; //index is based on "length" value
int res2[10][10] = {0, }; //index is based on "length" value
and then
for (i =0; i < length; i++)
{
for (j =0; j < length; j++)
{
res1[i][j] = 0;
res2[i][j] = 1;//notzero
}
}
Here D[i,j] and S[i,j] are represented by res1[10][10] and res2[10][10], respectively. These are called two-dimentional array.
I guess struct will be your friend here depending on what you actually want to work with.
Struct would be fine if, say, pair of states creates some kind of entity.
Otherwise You could use two-dimensional array.
After accept answer.
Depending on coding goals and platform, to get "simple and fast" using a pointer to pointer to a number may be faster then a 2-D array in C.
// 2-D array
double x[MAX_ROW][MAX_COL];
// Code computes the address in `x`, often involving a i*MAX_COL, if not in a loop.
// Slower when multiplication is expensive and random array access occurs.
x[i][j] = f();
// pointer to pointer of double
double **y = calloc(MAX_ROW, sizeof *y);
for (i=0; i<MAX_ROW; i++) y[i] = calloc(MAX_COL, sizeof *(y[i]));
// Code computes the address in `y` by a lookup of y[i]
y[i][j] = f();
Flexibility
The first data type is easy print(x), when the array size is fixed, but becomes challenging otherwise.
The 2nd data type is easy print(y, rows, columns), when the array size is variable and of course works well with fixed.
The 2nd data type also row swapping simply by swapping pointers.
So if code is using a fixed array size, use double x[MAX_ROW][MAX_COL], otherwise recommend double **y. YMMV

Resources