size of multi-dimensional array and qsort

B

bsder

Hi,

Can anyone please tell me how to calculate the size of the following
4-dimensional array, and now to use qsort for sorting on this array?

double sp[3] = { 4.0, 5.0, 6.0 };
double spa[3][2] = {
{ 4.0, 2.0 },
{ 5.0, 8.0 },
{ 6.0, 6.0 },
};

double spb[3][2][2] = {
{ {1.0, 2.0}, {3.0, 4.0} },
{ {5.0, 6.0}, {7.0, 8.0} },
{ {9.0, 10.0 }, {11.0, 12.0} },
};

// spc(Time, X, Y, Z)
double spc[3][1][1][1] = {
{ {{1.0}} },
{ {{5.0}} },
{ {{9.0}} },
};


for (int t=0; t<max_time; t++)
for (int x=0; x<max_x; x++)
for (int y=0; y<max_y; y++)
for (int z=0; z<max_z; z++)
qsort(...);

Thanks
D
 
M

Michael Mair

bsder said:
Hi,

Can anyone please tell me how to calculate the size of the following
4-dimensional array, and now to use qsort for sorting on this array?

double sp[3] = { 4.0, 5.0, 6.0 };
double spa[3][2] = {
{ 4.0, 2.0 },
{ 5.0, 8.0 },
{ 6.0, 6.0 },
};

double spb[3][2][2] = {
{ {1.0, 2.0}, {3.0, 4.0} },
{ {5.0, 6.0}, {7.0, 8.0} },
{ {9.0, 10.0 }, {11.0, 12.0} },
};

// spc(Time, X, Y, Z)
double spc[3][1][1][1] = {
{ {{1.0}} },
{ {{5.0}} },
{ {{9.0}} },
};

Sizes:
sizeof sp
sizeof spa
sizeof spb
sizeof spc
If you want the number of elements per first dimension, you can use
sizeof sp/sizeof sp[0].
for (int t=0; t<max_time; t++)
for (int x=0; x<max_x; x++)
for (int y=0; y<max_y; y++)
for (int z=0; z<max_z; z++)
qsort(...);

The problem is: How do you want to sort?
You seem to want to sort along the highest dimension of spc:
If yes, pass spc[t][x][y] to qsort() along with a comparison
function for double* to achieve it.
If no, define "order" on a n-dimensional array with all dimensions
but one fixed or provide transformations to and from a 1D array
along with appropriate comparison functions.

Cheers
Michael
 
B

bsder

Michael said:
bsder said:
Hi,

Can anyone please tell me how to calculate the size of the following
4-dimensional array, and now to use qsort for sorting on this array?

double sp[3] = { 4.0, 5.0, 6.0 };
double spa[3][2] = {
{ 4.0, 2.0 },
{ 5.0, 8.0 },
{ 6.0, 6.0 },
};

double spb[3][2][2] = {
{ {1.0, 2.0}, {3.0, 4.0} },
{ {5.0, 6.0}, {7.0, 8.0} },
{ {9.0, 10.0 }, {11.0, 12.0} },
};

// spc(Time, X, Y, Z)
double spc[3][1][1][1] = {
{ {{1.0}} },
{ {{5.0}} },
{ {{9.0}} },
};


Sizes:
sizeof sp
sizeof spa
sizeof spb
sizeof spc
If you want the number of elements per first dimension, you can use
sizeof sp/sizeof sp[0].
for (int t=0; t<max_time; t++)
for (int x=0; x<max_x; x++)
for (int y=0; y<max_y; y++)
for (int z=0; z<max_z; z++)
qsort(...);


The problem is: How do you want to sort?
You seem to want to sort along the highest dimension of spc:
If yes, pass spc[t][x][y] to qsort() along with a comparison
function for double* to achieve it.
If no, define "order" on a n-dimensional array with all dimensions
but one fixed or provide transformations to and from a 1D array
along with appropriate comparison functions.

Cheers
Michael
Hi, I wrote the following version of passing 4-dimensional array in to a
function for printing, but there is an error when passing a
4-dimensional array in to the function.
Here is the code:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

void prn_sorted_distance(double *spc)
{
//qsort(spc, sizeof spc/sizeof *spc, sizeof *spc, compare);
}

void prn_distance(double *spb)
{
register int a,b,c, t,x,y,z;
x=y=z=0;
double tmp_x, tmp_y, tmp_z, distance, total;
int size_T = sizeof spb / sizeof spb[0];
int size_X = sizeof spb[0] / sizeof spb[0][0];
int size_Y = sizeof spb[0][0] / sizeof spb[0][0][0];
int size_Z = sizeof spb[0][0][0] / sizeof spb[0][0][0][0];
int x_co_ord, y_co_ord, z_co_ord;
for ( t = 0; t < size_T; t++ ) {
for ( x = 0; x < size_X; x++ ) {
tmp_x = 100.00-spb[t][x][y][z];
//printf("x: %6.1lf\n", spb[t][x][y][z]);
for ( y = 0; y < size_Y; y++ ) {
tmp_y = 100.00-spb[t][x][y][z];
//printf("y: %6.1lf\n", spb[t][x][y][z]);
for ( z = 0; z < size_Z; z++ ) {
printf("z: %6.1lf; ", spb[t][x][y][z]);
tmp_z = 100.00-spb[t][x][y][z];
a = tmp_x * tmp_x;
b = tmp_y * tmp_y;
c = tmp_z * tmp_z;
total = a + b + c;
distance = sqrt(total);
printf("distance: %6.1lf\n", distance);
}
}
}
}
}

int main()
{
double spb[3][1][1][1] = {
{ {{1.0}} },
{ {{5.0}} },
{ {{9.0}} },
};

prn_distance(&spb);
//prn_sort_distance(spb);

return 1;
}

I haven't implement the function for comparison. The comparison will be
based on distance of two points. But I need to solve the array passing
by reference first.

Thanks
D
 
L

Lawrence Kirby

Hi,

Can anyone please tell me how to calculate the size of the following
4-dimensional array, and now to use qsort for sorting on this array?

You'll need to explain what you mean by "sorting" a 4-dimensional array.
Sorting is inherently a 1D process, there is no single way in which a 4D
array might be considered "sorted".
double sp[3] = { 4.0, 5.0, 6.0 };
double spa[3][2] = {
{ 4.0, 2.0 },
{ 5.0, 8.0 },
{ 6.0, 6.0 },
};

double spb[3][2][2] = {
{ {1.0, 2.0}, {3.0, 4.0} },
{ {5.0, 6.0}, {7.0, 8.0} },
{ {9.0, 10.0 }, {11.0, 12.0} },
};

// spc(Time, X, Y, Z)
double spc[3][1][1][1] = {
{ {{1.0}} },
{ {{5.0}} },
{ {{9.0}} },
};

In this case it is fairly obvious because the array is degenerate: only
one dimension has a size other then 1. Here you could write

qsort(spc, sizeof spc/sizeof *spc, sizeof *spc, compare);

This works when other dimensions are greater than 1, as long as you are
just viewing the array as a 1D array of "rows" where each row happens to
be an array in its own right. The comparison function will need to sort
out the details of how to compare 2 complete rows in a valid way.

Lawrence
 
B

bsder

Lawrence said:
Hi,

Can anyone please tell me how to calculate the size of the following
4-dimensional array, and now to use qsort for sorting on this array?


You'll need to explain what you mean by "sorting" a 4-dimensional array.
Sorting is inherently a 1D process, there is no single way in which a 4D
array might be considered "sorted".

double sp[3] = { 4.0, 5.0, 6.0 };
double spa[3][2] = {
{ 4.0, 2.0 },
{ 5.0, 8.0 },
{ 6.0, 6.0 },
};

double spb[3][2][2] = {
{ {1.0, 2.0}, {3.0, 4.0} },
{ {5.0, 6.0}, {7.0, 8.0} },
{ {9.0, 10.0 }, {11.0, 12.0} },
};

// spc(Time, X, Y, Z)
double spc[3][1][1][1] = {
{ {{1.0}} },
{ {{5.0}} },
{ {{9.0}} },
};


In this case it is fairly obvious because the array is degenerate: only
one dimension has a size other then 1. Here you could write

qsort(spc, sizeof spc/sizeof *spc, sizeof *spc, compare);

This works when other dimensions are greater than 1, as long as you are
just viewing the array as a 1D array of "rows" where each row happens to
be an array in its own right. The comparison function will need to sort
out the details of how to compare 2 complete rows in a valid way.
I feel abit trouble creating a "compare" function for the comparison of
two different 2D arrays. Is there any simple example I can follow?

Thanks
D
 
B

bsder

bsder said:
Lawrence said:
Hi,

Can anyone please tell me how to calculate the size of the following
4-dimensional array, and now to use qsort for sorting on this array?



You'll need to explain what you mean by "sorting" a 4-dimensional array.
Sorting is inherently a 1D process, there is no single way in which a 4D
array might be considered "sorted".

double sp[3] = { 4.0, 5.0, 6.0 };
double spa[3][2] = {
{ 4.0, 2.0 },
{ 5.0, 8.0 },
{ 6.0, 6.0 },
};

double spb[3][2][2] = {
{ {1.0, 2.0}, {3.0, 4.0} },
{ {5.0, 6.0}, {7.0, 8.0} },
{ {9.0, 10.0 }, {11.0, 12.0} },
};

// spc(Time, X, Y, Z)
double spc[3][1][1][1] = {
{ {{1.0}} },
{ {{5.0}} },
{ {{9.0}} },
};



In this case it is fairly obvious because the array is degenerate: only
one dimension has a size other then 1. Here you could write

qsort(spc, sizeof spc/sizeof *spc, sizeof *spc, compare);

This works when other dimensions are greater than 1, as long as you are
just viewing the array as a 1D array of "rows" where each row happens to
be an array in its own right. The comparison function will need to sort
out the details of how to compare 2 complete rows in a valid way.

I feel abit trouble creating a "compare" function for the comparison of
two different 2D arrays. Is there any simple example I can follow?
Here is what I got now:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

void prn_sorted_distance(double spc[][4], int n)
{
//qsort(spc, sizeof spc/sizeof *spc, sizeof *spc, compare);
printf("size_spc*: %d\n", sizeof *spc);
qsort(spc, n, sizeof *spc, compare);
}

void prn_distance(double spb[][4], int n)
{
register int x,y,z, t,coor=0;
double distance, total;
int size_coor = sizeof spb[0] / sizeof spb[0][0];
double tmp[size_coor];
if (n == 0 || size_coor < 3)
return;

for ( t = 0; t < n; t++ ) {
for ( coor = 0; coor < size_coor; coor++ ) {
printf("point: %6.1lf; ", spb[t][coor]);
tmp[coor] = 100.00-spb[t][coor];
}
x = tmp[0] * tmp[0];
y = tmp[1] * tmp[1];
z = tmp[2] * tmp[2];
distance = sqrt(x+y+z);
printf("distance: %6.1lf\n", distance);
}
}

int main()
{
double spb[3][4] = {
{1.0, 2.0, 1.0, 3.0},
{8.0, 3.0, 12.0, 8.0},
{4.0, 7.0, 2.0, 5.0}
};

int size_elem = sizeof spb / sizeof spb[0];
prn_distance(spb, size_elem);
printf("--------------------------\n");
printf("size_spc: %d\n", sizeof spb/sizeof *spb);
printf("size_spc*: %d\n", sizeof *spb);
prn_sorted_distance(spb, size_elem);

return 1;
}

Thanks
 
B

bsder

bsder said:
bsder said:
Lawrence said:
On Thu, 14 Jul 2005 05:48:23 +0000, bsder wrote:


Hi,

Can anyone please tell me how to calculate the size of the following
4-dimensional array, and now to use qsort for sorting on this array?




You'll need to explain what you mean by "sorting" a 4-dimensional array.
Sorting is inherently a 1D process, there is no single way in which a 4D
array might be considered "sorted".


double sp[3] = { 4.0, 5.0, 6.0 };
double spa[3][2] = {
{ 4.0, 2.0 },
{ 5.0, 8.0 },
{ 6.0, 6.0 },
};

double spb[3][2][2] = {
{ {1.0, 2.0}, {3.0, 4.0} },
{ {5.0, 6.0}, {7.0, 8.0} },
{ {9.0, 10.0 }, {11.0, 12.0} },
};

// spc(Time, X, Y, Z)
double spc[3][1][1][1] = {
{ {{1.0}} },
{ {{5.0}} },
{ {{9.0}} },
};




In this case it is fairly obvious because the array is degenerate: only
one dimension has a size other then 1. Here you could write

qsort(spc, sizeof spc/sizeof *spc, sizeof *spc, compare);

This works when other dimensions are greater than 1, as long as you are
just viewing the array as a 1D array of "rows" where each row happens to
be an array in its own right. The comparison function will need to sort
out the details of how to compare 2 complete rows in a valid way.


I feel abit trouble creating a "compare" function for the comparison
of two different 2D arrays. Is there any simple example I can follow?
Here is what I got now:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

void prn_sorted_distance(double spc[][4], int n)
{
//qsort(spc, sizeof spc/sizeof *spc, sizeof *spc, compare);
printf("size_spc*: %d\n", sizeof *spc);
qsort(spc, n, sizeof *spc, compare);
}

void prn_distance(double spb[][4], int n)
{
register int x,y,z, t,coor=0;
double distance, total;
int size_coor = sizeof spb[0] / sizeof spb[0][0];
double tmp[size_coor];
if (n == 0 || size_coor < 3)
return;

for ( t = 0; t < n; t++ ) {
for ( coor = 0; coor < size_coor; coor++ ) {
printf("point: %6.1lf; ", spb[t][coor]);
tmp[coor] = 100.00-spb[t][coor];
}
x = tmp[0] * tmp[0];
y = tmp[1] * tmp[1];
z = tmp[2] * tmp[2];
distance = sqrt(x+y+z);
printf("distance: %6.1lf\n", distance);
}
}

int main()
{
double spb[3][4] = {
{1.0, 2.0, 1.0, 3.0},
{8.0, 3.0, 12.0, 8.0},
{4.0, 7.0, 2.0, 5.0}
};

int size_elem = sizeof spb / sizeof spb[0];
prn_distance(spb, size_elem);
printf("--------------------------\n");
printf("size_spc: %d\n", sizeof spb/sizeof *spb);
printf("size_spc*: %d\n", sizeof *spb);
prn_sorted_distance(spb, size_elem);

return 1;
}
I actually want to compare the distance of each row in this 2D array.
 
K

Kenny McCormack

bsder said:
I haven't implement the function for comparison. The comparison will be
based on distance of two points. But I need to solve the array passing
by reference first.

Thanks for keeping us posted. Good luck in your endeavors.

Oh, no, thank *you*! You've done all the work. We appreciate it.
 
B

bsder

Kenny said:
Thanks for keeping us posted. Good luck in your endeavors.




Oh, no, thank *you*! You've done all the work. We appreciate it.
Execuse me, what do you meant?
 
B

bsder

Hi,

I finally written a full program with comparison in a 2-dimensional
array. But the compilation is not successful. It appeared I didn't pass
in the correct method "compare".
Can anyone please point me to the direction how to correct this error?
Here is the program:


#include <stdlib.h>
#include <math.h>

int compare(const double *rowA, const double *rowB)
{
double diffA[3], diffB[3], distance[2];
diffA[0] = 100.0 - *rowA+1;
diffA[1] = 100.0 - *rowA+2;
diffA[2] = 100.0 - *rowA+3;

diffA[0] = 100.0 - *rowB+1;
diffA[1] = 100.0 - *rowB+2;
diffA[2] = 100.0 - *rowB+3;

distance[0] = sqrt(diffA[0]+diffA[1]+diffA[2]);
distance[1] = sqrt(diffB[0]+diffB[1]+diffB[2]);

return 0 ? distance[0] > distance[1] : 1;
}

void prn_sorted_distance(double spc[][4], int n)
{
//qsort(spc, sizeof spc/sizeof *spc, sizeof *spc, compare);
printf("size_spc*: %d\n", sizeof *spc);
qsort(spc, n, sizeof *spc, compare);
prn_distance(spb, n);
}

void prn_distance(double spb[][4], int n)
{
register int x,y,z, t,coor=0;
double distance;
int size_coor = sizeof spb[0] / sizeof spb[0][0];
double tmp[size_coor];
if (n == 0 || size_coor < 3)
return;

for ( t = 0; t < n; t++ ) {
for ( coor = 0; coor < size_coor; coor++ ) {
printf("point: %6.1lf; ", spb[t][coor]);
tmp[coor] = 100.00-spb[t][coor];
}
x = tmp[0] * tmp[0];
y = tmp[1] * tmp[1];
z = tmp[2] * tmp[2];
distance = sqrt(x+y+z);
printf("distance: %6.1lf\n", distance);
}
}

int main()
{
double spb[3][4] = {
{1.0, 2.0, 1.0, 3.0},
{8.0, 3.0, 12.0, 8.0},
{4.0, 7.0, 2.0, 5.0}
};

int size_elem = sizeof spb / sizeof spb[0];
prn_distance(spb, size_elem);
printf("--------------------------\n");
printf("size_spc: %d\n", sizeof spb/sizeof *spb);
printf("size_spc*: %d\n", sizeof *spb);
prn_sorted_distance(spb, size_elem);

return 1;
}

Thanks
D
 
B

bsder

Hi,

After made an attempt to change the function "compare", I still can't
get the sorting workout correctly.
Here is the code:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int compare(const double *rowA, const double *rowB)
{
double diffA[3], diffB[3], distance[2];
printf("DA1_row: %6.1lf\n", rowA[1]);
printf("DA2_row: %6.1lf\n", rowA[2]);
printf("DA3_row: %6.1lf\n\n", rowA[3]);
printf("DB1_row: %6.1lf\n", rowB[1]);
printf("DB2_row: %6.1lf\n", rowB[2]);
printf("DB3_row: %6.1lf\n\n", rowB[3]);

diffA[0] = 100.0 - rowA[1];
diffA[1] = 100.0 - rowA[2];
diffA[2] = 100.0 - rowA[3];

diffB[0] = 100.0 - rowB[1];
diffB[1] = 100.0 - rowB[2];
diffB[2] = 100.0 - rowB[3];

distance[0] =
sqrt(diffA[0]*diffA[0]+diffA[1]*diffA[1]+diffA[2]*diffA[2]);
distance[1] =
sqrt(diffB[0]*diffB[0]+diffB[1]*diffB[1]+diffB[2]*diffB[2]);

printf("Comp_p1: %6.1lf; ", distance[0]);
printf("Comp_p2: %6.1lf\n", distance[1]);

return 1 ? distance[0] > distance[1] : 0;
}
void prn_distance(double spb[][4], int n)
{
register int x,y,z, t,coor=0;
double distance;
int size_coor = sizeof spb[0] / sizeof spb[0][0];
double tmp[size_coor];
if (n == 0 || size_coor < 3)
return;

for ( t = 0; t < n; t++ ) {
for ( coor = 0; coor < size_coor; coor++ ) {
printf("point: %6.1lf; ", spb[t][coor]);
tmp[coor] = 100.00-spb[t][coor];
}
x = tmp[0] * tmp[0];
y = tmp[1] * tmp[1];
z = tmp[2] * tmp[2];
distance = sqrt(x+y+z);
printf("distance: %6.1lf\n", distance);
}
}

void prn_sorted_distance(double spc[][4], int n)
{
//qsort(spc, sizeof spc/sizeof *spc, sizeof *spc, compare);
printf("size_spc*: %d\n", sizeof *spc);
qsort(spc, n, sizeof *spc, (int (*)(const void *, const void
*))compare);
prn_distance(spc, n);
}

int main()
{
double spb[5][4] = {
{1.0, 2.0, 1.0, 3.0},
{8.0, 3.0, 12.0, 8.0},
{4.0, 7.0, 2.0, 5.0},
{8.0, 1.0, 2.0, 1.0},
{9.0, 92.0, 81.0, 93.0}
};

int size_elem = sizeof spb / sizeof spb[0];
prn_distance(spb, size_elem);
printf("--------------------------\n");
printf("size_spc: %d\n", sizeof spb/sizeof *spb);
printf("size_spc*: %d\n", sizeof *spb);
prn_sorted_distance(spb, size_elem);

return 1;
}

D
 
L

Lawrence Kirby

Hi,

I finally written a full program with comparison in a 2-dimensional
array. But the compilation is not successful. It appeared I didn't pass
in the correct method "compare".

compare isn't a method, it is a function.
Can anyone please point me to the direction how to correct this error?
Here is the program:


#include <stdlib.h>
#include <math.h>

You need to include said:
int compare(const double *rowA, const double *rowB)
{

qsort() requires a comparison function that takes 2 const void *
arguments, you've defined one that take 2 const double * arguments i.e.
your function does not meet the specification. If you wanted to sort an
array of doubles you might write:

int compare(const void *vA, const void *vB)
{
const double *rowA = vA;
const double *rowB = vB;

But looking below you're not doing that, you're trying to sort an array
of arrays of double. The first argument you pass to qsort() has type
pointer to an array of 4 doubles or double (*)[4] i.e. the elements to be
sorted each have type array of 4 doubles. qsort() passes a pointer to the
element converted to void *, and that is the type you need to convert back
to:

int compare(const void *vA, const void *vB)
{
const double *rowA = *(const double (*)[4])vA;
const double *rowB = *(const double (*)[4])vB;

The cast converts to the correct pointer to array type, this pointer is
then dereferenced to give the element to be compared (an array), that
array is then automatically converted to a pointer to its first element
which is assigned.
double diffA[3], diffB[3], distance[2];
diffA[0] = 100.0 - *rowA+1;
diffA[1] = 100.0 - *rowA+2;
diffA[2] = 100.0 - *rowA+3;

diffA[0] = 100.0 - *rowB+1;
diffA[1] = 100.0 - *rowB+2;
diffA[2] = 100.0 - *rowB+3;

Should these be diffB? Do you mean rowA[1] etc.?
distance[0] = sqrt(diffA[0]+diffA[1]+diffA[2]);
distance[1] = sqrt(diffB[0]+diffB[1]+diffB[2]);

Should those be sums of squares? Also sqrt() is pointless here because it
won't change the relative ordering of the 2 values except for limits of
accuracy issues.
return 0 ? distance[0] > distance[1] : 1;

Did you mean

return distance[0] > distance[1] ? 0 : 1;

This isn't a valid comparison function. A valid comparison function must
produce a consistent total ordering of the array elements. For example if
X > Y then Y < X. Since this function never returns a value < 0 that is
clearly not the case for this function.

It would be a lot safer (and quite probably faster) to generate a separate
array of "distance" values, or square of distance values, and then sort on
that.
}
void prn_sorted_distance(double spc[][4], int n) {
//qsort(spc, sizeof spc/sizeof *spc, sizeof *spc, compare);
printf("size_spc*: %d\n", sizeof *spc);

the result of sizeof has type size_t, not int, so it is not valid to use a
%d conversion specifier for it. A simple fix is:

printf("size_spc*: %d\n", (int)sizeof *spc);
qsort(spc, n, sizeof *spc, compare);

Correct, your commented out version is invalid because spc isn't an array,
it is a pointer. You cannot pass arrays as function arguments in C, the
true type of spc is double (*)[4] i.e. a pointer to an array of 4 doubles.
prn_distance(spb, n);
}
}
void prn_distance(double spb[][4], int n) {
register int x,y,z, t,coor=0;
double distance;
int size_coor = sizeof spb[0] / sizeof spb[0][0]; double
tmp[size_coor];
if (n == 0 || size_coor < 3)
return;

for ( t = 0; t < n; t++ ) {
for ( coor = 0; coor < size_coor; coor++ ) {
printf("point: %6.1lf; ", spb[t][coor]); tmp[coor] =
100.00-spb[t][coor];
}
x = tmp[0] * tmp[0];
y = tmp[1] * tmp[1];
z = tmp[2] * tmp[2];
distance = sqrt(x+y+z);
printf("distance: %6.1lf\n", distance);
}
}
}
int main()
{
double spb[3][4] = {
{1.0, 2.0, 1.0, 3.0},
{8.0, 3.0, 12.0, 8.0},
{4.0, 7.0, 2.0, 5.0}
};

int size_elem = sizeof spb / sizeof spb[0]; prn_distance(spb,
size_elem);
printf("--------------------------\n");
printf("size_spc: %d\n", sizeof spb/sizeof *spb); printf("size_spc*:
%d\n", sizeof *spb);
prn_sorted_distance(spb, size_elem);

return 1;

There are 3 portable values you can return from the initial invocation of
main(): 0, EXIT_SUCCESS and EXIT_FAILURE. The first 2 indicate success,
the last 2 are macros defined in <stdlib.h>.

Lawrence
 
B

Barry Schwarz

snip 50+ irrelevant lines. Please trim your quotes.
Hi, I wrote the following version of passing 4-dimensional array in to a
function for printing, but there is an error when passing a
4-dimensional array in to the function.
Here is the code:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

void prn_sorted_distance(double *spc)
{
//qsort(spc, sizeof spc/sizeof *spc, sizeof *spc, compare);
}

void prn_distance(double *spb)

Here you say the function will receive a pointer to double.
{
register int a,b,c, t,x,y,z;
x=y=z=0;
double tmp_x, tmp_y, tmp_z, distance, total;
int size_T = sizeof spb / sizeof spb[0];

Since spb is a pointer to double, spb[0] is a double (spb is
dereferenced).

Unfortunately, sizeof spb evaluates to the size of the pointer, not
the size of the array it points to. There is no way generic technique
that can be used inside a function to determine the size of an array
that is passed as an argument. Common techniques used to get around
this limitation are 1) to pass the size as a parameter, to use a
#define macro or a global enum value for the size, and 3) to use a
sentinel value in the array that signals the end of the data.

Since you obviously intend to pass a 4D array, define the function
exactly that way. It is true that the argument will automatically be
converted to a pointer by the compiler, but in this case it will have
type pointer to 3D array. Based on the array in main, the function
should look like
void prn_distance(double spb[3][1][1][1])
but you can replace the [3] with just []. (The first dimension of an
array parameter can be omitted.) Within the function, spb would have
type double (*)[1][1][1]. All of your size expressions will work
correctly except the first one. sizeof spb is still the size of the
pointer but now sizeof spb[0] is the size of the (first) array spb
points to. You still need some other technique for determining the
first dimension.
int size_X = sizeof spb[0] / sizeof spb[0][0];

This is a syntax error. spb[0][0] is not a valid expression. You
cannot dereference a double.
int size_Y = sizeof spb[0][0] / sizeof spb[0][0][0];
int size_Z = sizeof spb[0][0][0] / sizeof spb[0][0][0][0];
int x_co_ord, y_co_ord, z_co_ord;
for ( t = 0; t < size_T; t++ ) {
for ( x = 0; x < size_X; x++ ) {
tmp_x = 100.00-spb[t][x][y][z];
//printf("x: %6.1lf\n", spb[t][x][y][z]);
for ( y = 0; y < size_Y; y++ ) {
tmp_y = 100.00-spb[t][x][y][z];
//printf("y: %6.1lf\n", spb[t][x][y][z]);
for ( z = 0; z < size_Z; z++ ) {
printf("z: %6.1lf; ", spb[t][x][y][z]);
tmp_z = 100.00-spb[t][x][y][z];
a = tmp_x * tmp_x;
b = tmp_y * tmp_y;
c = tmp_z * tmp_z;
total = a + b + c;
distance = sqrt(total);
printf("distance: %6.1lf\n", distance);
}
}
}
}
}

int main()
{
double spb[3][1][1][1] = {
{ {{1.0}} },
{ {{5.0}} },
{ {{9.0}} },
};

spb is a 4D array of double.
prn_distance(&spb);

You are passing prn_distance a pointer to a 4D array of double. This
is also a syntax error since you promised that you would pass a
(simple) pointer to double. These two types of pointers are not at
all compatible.

If you change prn_distance as described above and remove the & here,
the types will match.
//prn_sort_distance(spb);

return 1;
}

I haven't implement the function for comparison. The comparison will be
based on distance of two points. But I need to solve the array passing
by reference first.

C does not pass by reference, it passes by value. In the case of an
array, that value is the address of the first element.


<<Remove the del for email>>
 
B

Barry Schwarz

Hi,

I finally written a full program with comparison in a 2-dimensional
array. But the compilation is not successful. It appeared I didn't pass
in the correct method "compare".

compare is a function. C does not have methods in the sense that C++
does.
Can anyone please point me to the direction how to correct this error?
Here is the program:


#include <stdlib.h>
#include <math.h>

int compare(const double *rowA, const double *rowB)

The compare function you pass to qsort must accept two pointers of
type const void*. You can later assign these pointers to pointers of
the correct/desired type within the function but not in the function
header
..
{
double diffA[3], diffB[3], distance[2];
diffA[0] = 100.0 - *rowA+1;
diffA[1] = 100.0 - *rowA+2;
diffA[2] = 100.0 - *rowA+3;

diffA[0] = 100.0 - *rowB+1;
diffA[1] = 100.0 - *rowB+2;
diffA[2] = 100.0 - *rowB+3;

You probably meant diffB here since otherwise you lose the first three
values.
distance[0] = sqrt(diffA[0]+diffA[1]+diffA[2]);
distance[1] = sqrt(diffB[0]+diffB[1]+diffB[2]);

return 0 ? distance[0] > distance[1] : 1;

You have the operands of the ?: operator out of order. Furthermore,
you need to be able to return three possible values: -1, 0, +1.
}

void prn_sorted_distance(double spc[][4], int n)
{
//qsort(spc, sizeof spc/sizeof *spc, sizeof *spc, compare);
printf("size_spc*: %d\n", sizeof *spc);
qsort(spc, n, sizeof *spc, compare);
prn_distance(spb, n);
}

void prn_distance(double spb[][4], int n)
{
register int x,y,z, t,coor=0;
double distance;
int size_coor = sizeof spb[0] / sizeof spb[0][0];
double tmp[size_coor];
if (n == 0 || size_coor < 3)
return;

for ( t = 0; t < n; t++ ) {
for ( coor = 0; coor < size_coor; coor++ ) {
printf("point: %6.1lf; ", spb[t][coor]);
tmp[coor] = 100.00-spb[t][coor];
}
x = tmp[0] * tmp[0];
y = tmp[1] * tmp[1];
z = tmp[2] * tmp[2];
distance = sqrt(x+y+z);
printf("distance: %6.1lf\n", distance);
}
}

int main()
{
double spb[3][4] = {
{1.0, 2.0, 1.0, 3.0},
{8.0, 3.0, 12.0, 8.0},
{4.0, 7.0, 2.0, 5.0}
};

int size_elem = sizeof spb / sizeof spb[0];
prn_distance(spb, size_elem);
printf("--------------------------\n");
printf("size_spc: %d\n", sizeof spb/sizeof *spb);
printf("size_spc*: %d\n", sizeof *spb);
prn_sorted_distance(spb, size_elem);

return 1;
}

Thanks
D



<<Remove the del for email>>
 
B

Barry Schwarz

Hi,

After made an attempt to change the function "compare", I still can't
get the sorting workout correctly.
Here is the code:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int compare(const double *rowA, const double *rowB)
{
double diffA[3], diffB[3], distance[2];
printf("DA1_row: %6.1lf\n", rowA[1]);
printf("DA2_row: %6.1lf\n", rowA[2]);
printf("DA3_row: %6.1lf\n\n", rowA[3]);

What about rowA[0]?
printf("DB1_row: %6.1lf\n", rowB[1]);
printf("DB2_row: %6.1lf\n", rowB[2]);
printf("DB3_row: %6.1lf\n\n", rowB[3]);

diffA[0] = 100.0 - rowA[1];
diffA[1] = 100.0 - rowA[2];
diffA[2] = 100.0 - rowA[3];

diffB[0] = 100.0 - rowB[1];
diffB[1] = 100.0 - rowB[2];
diffB[2] = 100.0 - rowB[3];

distance[0] =
sqrt(diffA[0]*diffA[0]+diffA[1]*diffA[1]+diffA[2]*diffA[2]);
distance[1] =
sqrt(diffB[0]*diffB[0]+diffB[1]*diffB[1]+diffB[2]*diffB[2]);

printf("Comp_p1: %6.1lf; ", distance[0]);
printf("Comp_p2: %6.1lf\n", distance[1]);

return 1 ? distance[0] > distance[1] : 0;
}
void prn_distance(double spb[][4], int n)
{
register int x,y,z, t,coor=0;
double distance;
int size_coor = sizeof spb[0] / sizeof spb[0][0];
double tmp[size_coor];
if (n == 0 || size_coor < 3)
return;

for ( t = 0; t < n; t++ ) {
for ( coor = 0; coor < size_coor; coor++ ) {
printf("point: %6.1lf; ", spb[t][coor]);
tmp[coor] = 100.00-spb[t][coor];
}
x = tmp[0] * tmp[0];
y = tmp[1] * tmp[1];
z = tmp[2] * tmp[2];
distance = sqrt(x+y+z);
printf("distance: %6.1lf\n", distance);
}
}

void prn_sorted_distance(double spc[][4], int n)
{
//qsort(spc, sizeof spc/sizeof *spc, sizeof *spc, compare);
printf("size_spc*: %d\n", sizeof *spc);
qsort(spc, n, sizeof *spc, (int (*)(const void *, const void
*))compare);
prn_distance(spc, n);
}

int main()
{
double spb[5][4] = {
{1.0, 2.0, 1.0, 3.0},
{8.0, 3.0, 12.0, 8.0},
{4.0, 7.0, 2.0, 5.0},
{8.0, 1.0, 2.0, 1.0},
{9.0, 92.0, 81.0, 93.0}
};

int size_elem = sizeof spb / sizeof spb[0];
prn_distance(spb, size_elem);
printf("--------------------------\n");
printf("size_spc: %d\n", sizeof spb/sizeof *spb);
printf("size_spc*: %d\n", sizeof *spb);
prn_sorted_distance(spb, size_elem);

return 1;
}

D



<<Remove the del for email>>
 
A

Artie Gold

This function should take `const void *'s; use them as initializers for
variables of the appropriate type.
{
double diffA[3], diffB[3], distance[2];
printf("DA1_row: %6.1lf\n", rowA[1]);
printf("DA2_row: %6.1lf\n", rowA[2]);
printf("DA3_row: %6.1lf\n\n", rowA[3]);

What about rowA[0]?
printf("DB1_row: %6.1lf\n", rowB[1]);
printf("DB2_row: %6.1lf\n", rowB[2]);
printf("DB3_row: %6.1lf\n\n", rowB[3]);

diffA[0] = 100.0 - rowA[1];
diffA[1] = 100.0 - rowA[2];
diffA[2] = 100.0 - rowA[3];

diffB[0] = 100.0 - rowB[1];
diffB[1] = 100.0 - rowB[2];
diffB[2] = 100.0 - rowB[3];

distance[0] =
sqrt(diffA[0]*diffA[0]+diffA[1]*diffA[1]+diffA[2]*diffA[2]);
distance[1] =
sqrt(diffB[0]*diffB[0]+diffB[1]*diffB[1]+diffB[2]*diffB[2]);

printf("Comp_p1: %6.1lf; ", distance[0]);
printf("Comp_p2: %6.1lf\n", distance[1]);

return 1 ? distance[0] > distance[1] : 0;

You realize, of course, that the above line is equivalent to

return distance[0] > distance[1];

[IOW, it's not what you want. You also need to revisit what it is the
qsort() function expects in terms of the semantics of the comparison
function.]
}
void prn_distance(double spb[][4], int n)
{
register int x,y,z, t,coor=0;
double distance;
int size_coor = sizeof spb[0] / sizeof spb[0][0];

`size_coor' will always be 4, your function signature says so.
double tmp[size_coor];
if (n == 0 || size_coor < 3)
return;

for ( t = 0; t < n; t++ ) {
for ( coor = 0; coor < size_coor; coor++ ) {
printf("point: %6.1lf; ", spb[t][coor]);
tmp[coor] = 100.00-spb[t][coor];
}
x = tmp[0] * tmp[0];
y = tmp[1] * tmp[1];
z = tmp[2] * tmp[2];
distance = sqrt(x+y+z);
printf("distance: %6.1lf\n", distance);
}
}

void prn_sorted_distance(double spc[][4], int n)
{
//qsort(spc, sizeof spc/sizeof *spc, sizeof *spc, compare);
printf("size_spc*: %d\n", sizeof *spc);
qsort(spc, n, sizeof *spc, (int (*)(const void *, const void
*))compare);
Ugly cast. Write your `compare' function as expected by qsort -- it's
what void *s are *for*!
prn_distance(spc, n);
}

int main()
{
double spb[5][4] = {
{1.0, 2.0, 1.0, 3.0},
{8.0, 3.0, 12.0, 8.0},
{4.0, 7.0, 2.0, 5.0},
{8.0, 1.0, 2.0, 1.0},
{9.0, 92.0, 81.0, 93.0}
};

int size_elem = sizeof spb / sizeof spb[0]; In this expression, you'll get the right answer
prn_distance(spb, size_elem);
printf("--------------------------\n");
printf("size_spc: %d\n", sizeof spb/sizeof *spb);
printf("size_spc*: %d\n", sizeof *spb);
prn_sorted_distance(spb, size_elem);

return 1;
Why are you returning 1? It's a non-standard return value --
particularly if you think that getting this far means something failed.
Have you (OP) got a good text?

HTH,
--ag
 
B

bsder

Artie said:
Barry Schwarz wrote:
....
In this expression, you'll get the right answer


Why are you returning 1? It's a non-standard return value --
particularly if you think that getting this far means something failed.
should it be exit(0) or return 0?

Thanks
D
 
M

Michael Mair

bsder said:
should it be exit(0) or return 0?

exit() needs <stdlib.h> and has well-defined portable semantics for
0, EXIT_SUCCESS, EXIT_FAILURE
If you want to exit with success from anywhere but main() and are
sure that this is a Good Thing, then use exit(0) or exit(EXIT_SUCCESS).
If you want to exit indicating a failure and are sure that you have
done everything you can do in terms of error handling, then use
exit(EXIT_FAILURE); sometimes, a message to stderr and going on as
good as possible may be better than killing a program after 99% of
a longish computation.
At the end of main(), I would use exit(EXIT_SUCCESS)/exit(0) only
if I used exit(EXIT_FAILURE) somewhere else in the program and felt
the need to actively exit() the program.

These are only rough rules of thumb to get started and by no means
exhaustive.


Cheers
Michael
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top