How to use 2D arrays inside a C struct? - c

I need to create a struct that holds a 2D array however the array size can vary so i cannot define it with a constant length. I tried to solve this with a double pointer only to find out the double pointer is not the same as a double array. So how can i do this?
struct GaussianKernel {
int r;
double weightSum;
double **kernel;
};
GaussianKernel initializeKernel2D(jdouble sigma){
int r = (int) ceil(3 * sigma);
int kernelLen = 2 * r + 1;
double G[kernelLen][kernelLen];
double weightSum = 0;
double temp;
for (int y = -r; y <= r; y++)
{
for (int x = -r; x <= r; x++)
{
temp = exp(-(pow(x, 2) + pow(y, 2)) / (2 * pow(sigma, 2))) / (2 * PI * pow(sigma, 2));
G[y + r][x + r] = temp;
weightSum = weightSum + temp;
}
}
struct GaussianKernel GKernel;
GKernel.r = r;
GKernel.kernel = G;
GKernel.weightSum = weightSum;
return GKernel;
}

YOu should allocate your 2D dynamic array as:
GKernel.kernel = malloc(kernelLen * sizeof(double *));
for(i=0;i<kernelLen;i++)
GKernel.kernel[i] = malloc(kernelLen * sizeof(double));
Then you can store values in GKernel.kernel as per logic of your program

Related

incompatible types when assigning to type 'double *' from type 'double' when trying to assign a pointer to a pointer

I am trying to write the following algorithm:
This is my code:
double fft(int lenXH, int* X) {
double wk;
int j, p = 0, o = 0, k;
double* e, * Xeven, * Xodd, * d, * Y;
if (lenXH == 1) return X[0];
Y = (double*)malloc((lenXH - 1) * sizeof(double));
e = (double*)malloc((lenXH / 2 - 1) * sizeof(double));
d = (double*)malloc((lenXH / 2 - 1) * sizeof(double));
Xeven = (double*)malloc((lenXH / 2) * sizeof(double));
Xodd = (double*)malloc((lenXH / 2) * sizeof(double));
for (j = 0; j < lenXH; j++) {
if (j % 2 == 0) Xeven[p++] = X[j];
else Xodd[o++] = X[j];
}
e = fft(lenXH / 2, Xeven);
d = fft(lenXH / 2, Xodd);
for (k = 0; k < lenXH / 2 - 1; k++) {
wk = pow(E, 2 * PI * I * k / lenXH);
Y[k] = e[k] + wk * d[k];
Y[k + lenXH / 2] = e[k] + wk * d[k];
}
return Y;
}
My problem is that I get the error "incompatible types when assigning to type 'double *' from type 'double'" . This is for
e = fft(lenXH / 2, Xeven);
d = fft(lenXH / 2, Xodd);
I have been stuck on this for some time so I thought maybe you could help. Please let me know if there are other mistakes. Thank you!
Your function signature says it returns a double, while you expected a double *.
Change
double fft(int lenXH, int* X) { //....
to
double * fft(int lenXH, int* X) { //.....
After that, you need to take care of the statements
if (lenXH == 1) return X[0];
where X is of type int *, so X[0] will be an int, which is neither compatible with double nor double *. Please make changes as necessary to return a double *.

In C returned error: -1073741819 (0xC0000005)

I program in C and I am testing my program and I don't understand why I get the error -1073741819 (0xC0000005). Here is the Code:
#include <stdio.h>
#include <stdlib.h>
double interpol(double x0, double y0, double x1, double y1, double h) {
double ergebnis = (y1 - y0) / (x1 - x0) * h;
printf("%.2f\n", ergebnis);
return ergebnis;
}
void interpol_array(double *x_org, double *y_org, int dim_org,
double *x_int, double *y_int, int dim_int,
int n) {
int j, i;
double h;
i = 0;
y_org[0] = y_int[0];
for (j = 1; j < dim_int; j++) {
if (j % (n + 1) == 0 && j != 0) {
i++;
x_int[j] = x_org[i];
y_int[j] = x_org[i];
continue;
}
printf("%.2f ", y_org[0]);
}
}
int main() {
/* Pointer erzeugen auf null setzen */
double *xArrayOriginal = NULL;
double *yArrayOriginal = NULL;
double *xArrayInterpol = NULL;
double *yArrayInterpol = NULL;
/**/
int dimOriginal = 2;
int n = 3;
int dimInterpol = (n + 1) * (dimOriginal + 1) - n; /*+1 wegen der null*/
int i, j;
double h;
/* Array für die Originalwerte erzeugen */
xArrayOriginal = (double *)malloc(dimOriginal * sizeof(double));
yArrayOriginal = (double *)malloc(dimOriginal * sizeof(double));
/*Array für das Interpolierte Array erzeugen*/
xArrayInterpol = (double *)malloc(dimInterpol * sizeof(double));
yArrayInterpol = (double *)malloc(dimInterpol * sizeof(double));
xArrayOriginal[0] = 0;
xArrayOriginal[1] = 1;
xArrayOriginal[2] = 2;
yArrayOriginal[0] = 2;
yArrayOriginal[1] = 4;
yArrayOriginal[2] = 8;
interpol_array(xArrayOriginal, yArrayOriginal, dimOriginal, xArrayInterpol,
yArrayInterpol, dimInterpol, n);
return 0;
}
In my program I have 4 dynamic arrays. 2 dynamic arrays for origin x and y values and 2 dynamic arrays for interpolated x and y values. I don't program the full interpolation because I got an error. Therefore I searched the error and found out that when I use
printf("%.2f ", y_org[0]);
I get the error that you can see above. Only when I change it to
printf("test");
it works fine. So why do I get this error. what is wrong with my array list?
In the function main, the lines
int dimOriginal = 2;
...
xArrayOriginal =(double *)malloc(dimOriginal*sizeof(double));
yArrayOriginal =(double *)malloc(dimOriginal*sizeof(double));
allocate arrays for 2 double elements each. However, the lines
xArrayOriginal[2] =2;
...
yArrayOriginal[2] =8;
write out of bounds of these arrays, as the only valid elements numbers are 0 and 1. This causes undefined behavior.
Also, in the function interpol_array, the following line causes undefined behavior:
y_org[0] = y_int[0];
This is because y_int has been assigned the value of yArrayInterpol in main, but the contents of yArrayInterpol has not been initialized.

Loop in basic C program

I can't find and resolve the error in this code.
I want Parray and Tarray to be filled with an iteration of the equation in the loop. I tried both for and while loop, but it seems that only the first member of the array is given proper value, and that value is lost by the beginning of a new cycle.
#include <stdio.h>
#include <stdlib.h>
int main() {
int i;
int j;
float dt,P_init,t_init,t_end;
dt = 0.03125;
P_init = 30;
t_init = 0;
t_end = 30;
int n_steps = 0;
n_steps = t_end/(float)dt;
int Parray[n_steps+1];
int Tarray[n_steps+1];
for (i=0; i<n_steps+1; i++)
{
Parray[i]=0;
Tarray[i]=0;
}
Parray[0] = P_init;
Tarray[0] = t_init;
int x;
float P,t,dpdt;
x = 1;
while (x < n_steps+1)
{
float s,d;
P = Parray[x-1];
t = Tarray[x-1];
dpdt = 0.7 * P * (1-(P/750)) - 20;
s = P + (dt * dpdt);
Parray[x] = s;
d = t + dt;
Tarray[x] = d;
x++;
printf("%f %f ",s,d);
}
return(0);
}
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int i, j, x;
float dt, P_init, t_init, t_end, P, t, dpdt;
dt = 0.03125;
P_init = 30;
t_init = 0;
t_end = 30;
int n_steps = 0;
n_steps = t_end / (float)dt;
// using float arrays
float Parray[n_steps+1];
float Tarray[n_steps+1];
for (i = 0; i < n_steps+1; i++)
Parray[i] = 0;
for (j = 0; j < n_steps+1; j++)
Tarray[j] = 0;
Parray[0] = P_init;
Tarray[0] = t_init;
for (x = 1; x < n_steps + 1; x++) {
float s , d;
P = Parray[x-1];
t = Tarray[x-1];
dpdt = 0.7 * P * (1 - (P / 750)) - 20;
s = P + (dt * dpdt);
Parray[x] = s;
d = t + dt;
Tarray[x] = d;
printf("%f %f\n", s, d);
}
return(0);
}
I changed the int arrarys to float arrays.
What do you actually calculate here?
This line
dpdt = 0.7 * P * (1-(P/750)) - 20;
It seems to have a float value, therefore the array must be float type, and ALL inputs you put in the array must be in FLOAT type.
Change this:
int Parray[n_steps+1];
int Tarray[n_steps+1];
to
float Parray[n_steps+1];
float Tarray[n_steps+1];
and
P_init = 30;
t_init = 0;
t_end = 30;
All of them should be 30.0, 0.0, 30.0
Don't forget this too:
Parray[i]=0;
Tarray[i]=0;
Change it to 0.0
In short, C is bad at differentiate between types, so if you declare a float array, all inputs must be x.0, not only x where x is an integer.

dynamic two dimensional array to static array

any body knows how to convert 2d dynamic array to static so that i can use it in lapacke. dgels function which only take static matrix in c?
when i use malloc it does not give correct answer. how can i use malloc so that it works with it.thankyou
#include <stdio.h>
#include <lapacke.h>
#include <conio.h>
int main (int argc, const char * argv[])
{
/*double a[5][3] = {1,1,1,2,3,4,3,5,2,4,2,5,5,4,3};*/
double b[5][2] = {-10,-3,12,14,14,12,16,16,18,16};
lapack_int info,m,n,lda,ldb,nrhs;
int i,j;
double **a;
a=(double**)malloc(5* sizeof(double*));
for (i=0;i<5;i++)
{
a[i]=(double*)malloc(3* sizeof(double));
}
a[0][0]=1;
a[0][1]=1;
a[0][2]=1;
a[1][0]=2;
a[1][1]=3;
a[1][2]=4;
a[2][0]=3;
a[2][1]=5;
a[2][2]=2;
a[3][0]=4;
a[3][1]=2;
a[3][2]=5;
a[4][0]=5;
a[4][1]=4;
a[4][2]=3;
m = 5;
n = 3;
nrhs = 2;
lda = 3;
ldb = 2;
info = LAPACKE_dgels(LAPACK_ROW_MAJOR,'N',m,n,nrhs,*a,lda,*b,ldb);
for(i=0;i<n;i++)
{
for(j=0;j<nrhs;j++)
{
printf("%lf ",b[i][j]);
}
printf("\n");
}
getch();
return(info);
}
I do not know lapacke.dgels but try to change:
double **a;
a=(double**)malloc(5* sizeof(double*));
for (i=0;i<5;i++)
{
a[i]=(double*)malloc(3* sizeof(double));
}
to:
double (*a)[3];
a = malloc(5 * 3 * sizeof(double));
a is not a 2d array, it is an array of pointers to separate 1d arrays. Passing *a to LAPACKE_dgels only gives it a pointer to the first row. It will have no way to know where all of the other rows were allocated since they were allocated independently. It wants the entire array to be in a single contiguous block of memory. a must be of type double*, not double**, and you don't dereference it when passing it. You must flatten the 2d indexes into 1d indexes yourself, using either row or column major form (which you tell the function).
EDIT
The following code allocates a flat 1d array with room for m*n doubles. It then fills the array by converting the 2d indices to 1d row-major indices using the formula row * n + col. If we wanted column-major indices, we would use col * m + row.
#include <stdio.h>
#include <lapacke.h>
#include <conio.h>
int main (int argc, const char * argv[])
{
double b[5][2] = {-10,-3,12,14,14,12,16,16,18,16};
lapack_int info,m,n,lda,ldb,nrhs;
int i,j;
double *a;
m = 5;
n = 3;
nrhs = 2;
lda = 3;
ldb = 2;
a = malloc(m * n * sizeof(double));
a[0 * n + 0] = 1;
a[0 * n + 1] = 1;
a[0 * n + 2] = 1;
a[1 * n + 0] = 2;
a[1 * n + 1] = 3;
a[1 * n + 2] = 4;
a[2 * n + 0] = 3;
a[2 * n + 1] = 5;
a[2 * n + 2] = 2;
a[3 * n + 0] = 4;
a[3 * n + 1] = 2;
a[3 * n + 2] = 5;
a[4 * n + 0] = 5;
a[4 * n + 1] = 4;
a[4 * n + 2] = 3;
info = LAPACKE_dgels(LAPACK_ROW_MAJOR,'N',m,n,nrhs,a,lda,*b,ldb);
for(i=0;i<n;i++)
{
for(j=0;j<nrhs;j++)
{
printf("%lf ",b[i][j]);
}
printf("\n");
}
getch();
return(info);
}

Multidimensional array index to row,col,depth values?

I have a few values which are offsets to a multidimensional array , and look like this :
static const int TILE_SIZE = 32;
int Offset2D = (y * TILE_SIZE) + (x * TILE_SIZE);
int Offset3D = (y * TILE_SIZE) + (x * TILE_SIZE) + (z * TILE_SIZE);
Now what i would like to do is to convert an offset to x,y,z pair , like so :
void ConvertBack(int offset,int size,int& x,int& y,int& z)
{
//What's wrong with this code ?
x = offset / size;
y = offset % size;
z = ??; //How to get Z?
}
or
//Get back offsets from any dimension ?
void ConvertBackComplex(unsigned int offset,int size,int* vector,int len)
{
for (int i = 0;i < len;i++)
{
vector[i] = offset ?... ?
}
}
...So far all of my attempts have failed....So i would really welcome any help!...
First of all I think you indexing system is a bit off. The way you have things arranged different values of x, y, and z can give the same offset. So, first of all, assuming that TILE_SIZE is how many cells of the array store the data for a given point:
myArray = new arr[xSize*ySize*zSize*TILESIZE]
int offset2D = (x*ySize*zSize + y*zSize)*TILE_SIZE;
int offset3D = (x*ySize*zSize + y*zSize + z)*TILE_SIZE;
To get x,y,z back from the offset one simply does the following:
temp = offset/TILE_SIZE;
x = temp/(ySize*zSize);
y = (temp%(ySize*zSize))/zSize;
z = (temp%(ySize*zSize))%zSize;
For multiple dimensions:
temp = offset/TILE_SIZE;
sizeProduct = 1;
for(int k=1; k<numDims; ++k)
{
sizeProduct*=size[k];
}
for(int i=0; i<numDims; ++i)
{
vector[i]=temp/sizeProduct;
temp = temp % sizeProduct;
if((i+1)<numDims)
{
sizeProduct/=sizes[i+1];
}
}
To calculate array sizes in multiple dimensions:
int arraySize = TILE_SIZE;
for(int i=0; i<numDims; ++i)
{
arraySize*=sizes[i];
}
To calculate array indices in multiple dimensions (assuming vector is your array of coordinates):
int index =0;
sizeProduct = 1;
for(int k=1; k<numDims; ++k)
{
sizeProduct*=size[k];
}
for(int i=0; i<numDims; ++i)
{
index+=sizeProduct*vector[i];
if((i+1)<numDims)
{
sizeProduct/=sizes[i+1];
}
}
index*=TILE_SIZE;
Assuming that all dimensions are TILE_SIZE long, your offset calculations are wrong. Let's say I have an array a which simulated 3d array with all dimensions TILE_SIZE long:
int a[TILE_SIZE * TILE_SIZE * TILE_SIZE];
Then point p with coordinates (x, y, z) would have an offset like this:
int p_offset = z * (TILE_SIZE * TILE_SIZE)
+ y * (TILE_SIZE)
+ x;
Reverse calculation is then:
int p_z = p_offset / (TILE_SIZE * TILE_SIZE);
int p_y = (p_offset - p_z * (TILE_SIZE * TILE_SIZE)) / TILE_SIZE;
int p_x = p_offset % TILE_SIZE;
You can choose different order of dimensions (x, y, z) but you have to be consistent.
Assuming the dimensions go from X to Y to Z (as in X represents the lowest dimension):
You can't use a single function to calculate both the 2D and 3D offsets back into coordinates.
For 2D:
void ConvertBack2D(int offset, int x_len, int &x, int &y)
{
y = offset / x_len;
x = offset % x_len;
}
For 3D:
void ConvertBack3D(int offset, int x_len, int y_len, int &x, int &y, int &z)
{
z = offset / (x_len * y_len);
y = (offset - (x * x_len * y_len)) / y_len;
x = (offset - (x * x_len * y_len)) % x_len;
}

Resources