translation from matlab to C object containing matrices undefinedlength of object

A

adinda

So what i need is this; (I'm very new at this,, programming in C I
mean...)

In matlab I had a while loop, and after each loop was done I added my
resulting matrix to an object. Seeing the loop is conditional to my
results I do not know in advance how many loops I need. The matrices
are Nx * Ny* Nz*6.

In C I put my matrices into 1D arrays. So I thought that if I use a
counter for each time i do a loop and the calloc and realloc function
that would work...But it doesnt seem to be working...Hope one of you
can help me.

This is a sample text which i use to test my programs...

Vnulpoint is my result matrix for which i used pointers. So Varray is
supposed to contain each of the Vnulpoint matrices...

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define nx 2
#define ny 2
#define nz 2

void max_array(double *, int,int *,double *);
int compare_doubles (double *, double *);
void vindminnietnul(double *,double *,int,int* );
void vindmaxnieteen(double *,double *,int ,int*);
main()
{ int i,j,s,kl;
int countergetal=6;
double
gradoud[nx*ny*nz*6]={5.569,6.9987,0.00987,98.7743,1009.8876,0.0009987};;
double *gradpointeroud,*gradpointernieuw;
double gradnieuw[nx*ny*nz*6];
double *Vnulpoint[nx*ny*nz];
double *Vnulpoint2[nx*ny*nz];
gradpointeroud=gradoud;
gradpointernieuw=gradnieuw;
int counter=1;
double *Varray;
Varray=calloc(1*(nx*ny*nz*6),sizeof(double));
while(counter<100)
{
for(i=0; i<nx; i++)
{ for(j=0; j<ny ; j++)
{ for(s=0; s<nz ; s++)
{


Vnulpoint[i+j*nx
+s*nx*ny]=calloc(countergetal,sizeof(double));
Vnulpoint2[i+j*nx
+s*nx*ny]=calloc(countergetal,sizeof(double));
for(kl=0;kl<countergetal;kl++)
{
*(Vnulpoint[i+j*nx+s*nx*ny]+kl)=0.12369*kl;
*(Vnulpoint[i+j*nx+s*nx*ny]+0)=1;

printf("%f\n ",*(Vnulpoint[i+j*nx+s*nx*ny]
+kl));
}
int maxindex;
double Vmax;
max_array(Vnulpoint[i+j*nx+s*nx*ny],
4,&maxindex,&Vmax);
printf("Het maximum volume is %f op locatie %d
\n",Vmax,maxindex);
Vnulpoint2[i+j*nx+s*nx*ny]=Vnulpoint[i+j*nx
+s*nx*ny];
printf("Het toegewezen volume is %f \t %f \t %f
\n",*(Vnulpoint2[i+j*nx+s*nx*ny]),*(Vnulpoint2[i+j*nx+s*nx*ny]
+1),*(Vnulpoint2[i+j*nx+s*nx*ny]+2));


int teller;
double Vsort[countergetal];
for(teller=0;teller<countergetal;teller++)
{
Vsort[teller]=*(Vnulpoint[i+j*nx+s*nx*ny]+teller);
}
for(kl=0;kl<countergetal;kl++)
{
printf("Vsort %d \t %f\n ",kl,Vsort[kl]);
}

qsort(Vsort,countergetal,sizeof(double),(int(*)(const void*,const
void*))compare_doubles);
for(kl=0;kl<countergetal;kl++)
{
printf("Vsort %d \t %f\n ",kl,Vsort[kl]);
}

int indexmaxnieteen;
vindmaxnieteen(Vsort,Vnulpoint[i+j*nx
+s*nx*ny],countergetal,&indexmaxnieteen);


printf("De index is %d\n", indexmaxnieteen);
Varray=(double
*)realloc(Varray,counter*(nx*ny*nz*6)*sizeof(double));
int tel;
for (tel=0;tel<6;tel++)
{
Varray[(counter-1)*(i+j*nx+s*nx*ny+tel*nx*ny*nz)]=*(Vnulpoint[i
+j*nx+s*nx*ny]+tel*nx*ny*nz);

}
printf("Varray is %f \t %f \t %f \n %f \t %f \t %f \n en counter
is %d \n", Varray[(counter-1)*(i+j*nx+s*nx*ny)],Varray[(counter-1)*(i
+j*nx+s*nx*ny+1)],Varray[(counter-1)*(i+j*nx+s*nx*ny
+2)],Varray[(counter-1)*(i+j*nx+s*nx*ny+3)],Varray[(counter-1)*(i+j*nx
+s*nx*ny+4)],Varray[(counter-1)*(i+j*nx+s*nx*ny
+5)],Varray[(counter-1)*(i+j*nx+s*nx*ny+6)],counter);


gradpointernieuw=gradpointeroud;

}
}
}
counter++;
}

}

void max_array(double *a, int num_elements,int *indexptmax,double
*maxpt)
{
int i;

*indexptmax=0;
*maxpt=a[0];



for (i=1; i<num_elements; i++)
{
if (a>*maxpt)
{
*maxpt=a;
*indexptmax=i;
}
}


return;
}

int compare_doubles (double *x, double *y)
{

if (*x > *y)
{
return 1;
}
else
{
if (*x < *y)
{
return -1;
}
else
{
return 0;
}
}
}

void vindminnietnul(double *V,double *Vl,int counternummer,int *index)
{ int nk,nn;

for(nk=0;nk<counternummer;nk++)
{ if ( *(V+nk)!=0)
{for (nn=0;nn<counternummer;nn++)
{
if (*(Vl+nn-1)==*(V+nk))
{
*index=nn;
}

}
break;
}

}

}

void vindmaxnieteen(double *V,double *Vl,int counternummer,int*index)
{ int nk,nn;

for(nk=0;nk<counternummer;nk++)
{ if ( *(V+(counternummer-1)-nk)!=1)
{for (nn=0;nn<counternummer;nn++)
{
if (*(Vl+nn)==*(V+(counternummer-1)-nk))
{
*index=nn;
}
}
break;
}
}
return;
}
 
D

dj3vande

So what i need is this; (I'm very new at this,, programming in C I
mean...)

In matlab I had a while loop, and after each loop was done I added my
resulting matrix to an object. Seeing the loop is conditional to my
results I do not know in advance how many loops I need. The matrices
are Nx * Ny* Nz*6.

In C I put my matrices into 1D arrays. So I thought that if I use a
counter for each time i do a loop and the calloc and realloc function
that would work...But it doesnt seem to be working...Hope one of you
can help me.

What is it doing, and what were you expecting?
Reducing your code to the smallest example that demonstrates the
problem will make it a lot easier for people to help you (and may
also lead you to the problem without external help).


dave
 
B

Ben Bacarisse

adinda said:
So what i need is this; (I'm very new at this,, programming in C I
mean...)

In matlab I had a while loop, and after each loop was done I added my
resulting matrix to an object. Seeing the loop is conditional to my
results I do not know in advance how many loops I need. The matrices
are Nx * Ny* Nz*6.

In C I put my matrices into 1D arrays.

That is an off choice. With 4D arrays it leads to code that makes my
head hurt just reading it. If, for some reason, you must do it this
way, at least provide an access function so the code is readable.
So I thought that if I use a
counter for each time i do a loop and the calloc and realloc function
that would work...But it doesnt seem to be working...Hope one of you
can help me.

That is a bit vague. Since I have no idea what it should do, it is
very unlikely that I can help fix it. At least say what is going
wrong.
This is a sample text which i use to test my programs...

Vnulpoint is my result matrix for which i used pointers. So Varray is
supposed to contain each of the Vnulpoint matrices...

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define nx 2
#define ny 2
#define nz 2

I'd add one for the magic number 6 that appears in a few places.
void max_array(double *, int,int *,double *);
int compare_doubles (double *, double *);
void vindminnietnul(double *,double *,int,int* );
void vindmaxnieteen(double *,double *,int ,int*);
main()
{ int i,j,s,kl;
int countergetal=6;
double
gradoud[nx*ny*nz*6]={5.569,6.9987,0.00987,98.7743,1009.8876,0.0009987};;
double *gradpointeroud,*gradpointernieuw;
double gradnieuw[nx*ny*nz*6];
double *Vnulpoint[nx*ny*nz];
double *Vnulpoint2[nx*ny*nz];
gradpointeroud=gradoud;
gradpointernieuw=gradnieuw;
int counter=1;
double *Varray;
Varray=calloc(1*(nx*ny*nz*6),sizeof(double));
while(counter<100)

Head starting to hurt. Add spaces, please!

Where you have calloc and realloc, you should check the return. In
this short of program, I'd write small array allocate (and
re-allocate) functions that just exit if the allocation fails.
{
for(i=0; i<nx; i++)
{ for(j=0; j<ny ; j++)
{ for(s=0; s<nz ; s++)
{


Vnulpoint[i+j*nx
+s*nx*ny]=calloc(countergetal,sizeof(double));
Vnulpoint2[i+j*nx
+s*nx*ny]=calloc(countergetal,sizeof(double));
for(kl=0;kl<countergetal;kl++)
{

Hmm... a for inside a for inside a for inside for inside a while. I
would try to find some way to decompose these loops into functions.
*(Vnulpoint[i+j*nx+s*nx*ny]+kl)=0.12369*kl;
*(Vnulpoint[i+j*nx+s*nx*ny]+0)=1;

printf("%f\n ",*(Vnulpoint[i+j*nx+s*nx*ny]
+kl));
}
int maxindex;
double Vmax;
max_array(Vnulpoint[i+j*nx+s*nx*ny],
4,&maxindex,&Vmax);
printf("Het maximum volume is %f op locatie %d
\n",Vmax,maxindex);
Vnulpoint2[i+j*nx+s*nx*ny]=Vnulpoint[i+j*nx
+s*nx*ny];
printf("Het toegewezen volume is %f \t %f \t %f
\n",*(Vnulpoint2[i+j*nx+s*nx*ny]),*(Vnulpoint2[i+j*nx+s*nx*ny]
+1),*(Vnulpoint2[i+j*nx+s*nx*ny]+2));


int teller;
double Vsort[countergetal];
for(teller=0;teller<countergetal;teller++)
{
Vsort[teller]=*(Vnulpoint[i+j*nx+s*nx*ny]+teller);
}
for(kl=0;kl<countergetal;kl++)
{
printf("Vsort %d \t %f\n ",kl,Vsort[kl]);
}

qsort(Vsort,countergetal,sizeof(double),(int(*)(const void*,const
void*))compare_doubles);

You can loose the cast if you write compare function differently. See
below.
for(kl=0;kl<countergetal;kl++)
{
printf("Vsort %d \t %f\n ",kl,Vsort[kl]);
}

int indexmaxnieteen;
vindmaxnieteen(Vsort,Vnulpoint[i+j*nx
+s*nx*ny],countergetal,&indexmaxnieteen);


printf("De index is %d\n", indexmaxnieteen);
Varray=(double
*)realloc(Varray,counter*(nx*ny*nz*6)*sizeof(double));

You don't need the cast. Also, do you really need to realloc? It
looks to me that know the final size at the start and you could just
allocate once. Of course, I am a bit lost by now, so I may have that
wrong.
int tel;
for (tel=0;tel<6;tel++)
{
Varray[(counter-1)*(i+j*nx+s*nx*ny+tel*nx*ny*nz)]=*(Vnulpoint[i
+j*nx+s*nx*ny]+tel*nx*ny*nz);

}
printf("Varray is %f \t %f \t %f \n %f \t %f \t %f \n en counter
is %d \n", Varray[(counter-1)*(i+j*nx+s*nx*ny)],Varray[(counter-1)*(i
+j*nx+s*nx*ny+1)],Varray[(counter-1)*(i+j*nx+s*nx*ny
+2)],Varray[(counter-1)*(i+j*nx+s*nx*ny+3)],Varray[(counter-1)*(i+j*nx
+s*nx*ny+4)],Varray[(counter-1)*(i+j*nx+s*nx*ny
+5)],Varray[(counter-1)*(i+j*nx+s*nx*ny+6)],counter);

Head really sore now!
gradpointernieuw=gradpointeroud;

}
}
}
counter++;
}

}

void max_array(double *a, int num_elements,int *indexptmax,double
*maxpt)
{
int i;

*indexptmax=0;
*maxpt=a[0];



for (i=1; i<num_elements; i++)
{
if (a>*maxpt)
{
*maxpt=a;
*indexptmax=i;
}
}


return;
}

int compare_doubles (double *x, double *y)
{

if (*x > *y)
{
return 1;
}
else
{
if (*x < *y)
{
return -1;
}
else
{
return 0;
}
}
}


I'd write:

int compare_doubles(const void *xvp, const void *yvp)
{
const double *xp = xvp;
const double *yp = yvp;
void vindminnietnul(double *V,double *Vl,int counternummer,int *index)
{ int nk,nn;

for(nk=0;nk<counternummer;nk++)
{ if ( *(V+nk)!=0)

You do this a lot. I think V[nk] is much clearer than *(V+nk).
{for (nn=0;nn<counternummer;nn++)
{
if (*(Vl+nn-1)==*(V+nk))
{
*index=nn;
}

}
break;
}

}

}

I think I see now the reason for 1D arrays. You'd like to process
them as above with a single loop rather than 4 nested for loops. I
would not worry about that. It is almost always better to write the
clearest code you can, and then fiddle with it if you need t speed it
up. [You would get away with treating a 4D array as a 1D one (if it
comes to that) on all the compilers you are every likely to meet.]
void vindmaxnieteen(double *V,double *Vl,int counternummer,int*index)
{ int nk,nn;

for(nk=0;nk<counternummer;nk++)
{ if ( *(V+(counternummer-1)-nk)!=1)
{for (nn=0;nn<counternummer;nn++)
{
if (*(Vl+nn)==*(V+(counternummer-1)-nk))
{
*index=nn;
}
}
break;
}
}
return;
}

Serious question: why re-write in C? It is not the obvious choice for
this sort of thing.
 
A

adinda

Well actually this is just a test file. In my actual main file i don't
know my count until i've completed the loop (because my magnetic
energy needs to agree with my constraints, and i don't know how many
times I have to do the loop)
I put my 4D arrays in 1D because my collegues do that too and then we
can interchange code.
The reason why i'm translating in C is because matlab is slow. and C
is supposed to be faster (I hope)

Thanks for the tips,

Adinda
 
B

Ben Bacarisse

It helps if you quote a bit of the reply you are commenting on.

adinda said:
Well actually this is just a test file. In my actual main file i don't
know my count until i've completed the loop (because my magnetic
energy needs to agree with my constraints, and i don't know how many
times I have to do the loop)

OK, so you probably need realloc.
I put my 4D arrays in 1D because my collegues do that too and then we
can interchange code.

An excellent reason, though they should reconsider as well!
The reason why i'm translating in C is because matlab is slow. and C
is supposed to be faster (I hope)

OK. I meant why C specifically. Fortran used to be the language of
choice for such things but if your colleagues have chosen it, you must
follow.
Thanks for the tips,

There are unlikely to be any more unless you can say (in way that is
not domain specific) what was wrong with the program you posted.
 
F

Flash Gordon

Ben Bacarisse wrote, On 25/04/08 15:28:
printf("Varray is %f \t %f \t %f \n %f \t %f \t %f \n en counter
is %d \n", Varray[(counter-1)*(i+j*nx+s*nx*ny)],Varray[(counter-1)*(i
+j*nx+s*nx*ny+1)],Varray[(counter-1)*(i+j*nx+s*nx*ny
+2)],Varray[(counter-1)*(i+j*nx+s*nx*ny+3)],Varray[(counter-1)*(i+j*nx
+s*nx*ny+4)],Varray[(counter-1)*(i+j*nx+s*nx*ny
+5)],Varray[(counter-1)*(i+j*nx+s*nx*ny+6)],counter);

Head really sore now!

<snip>

I'm not surprised. However, when poked gcc gives the following warning
for this line...
t.c:94: warning: format ‘%d’ expects type ‘int’, but argument 8 has type
‘double’
So I suspect the OP has either too many parameters or too fe format
specifiers.

It also pointed out that Vsort is a variable sized array. In the full
code this may or may not be appropriate, but as far as I can see in the
example countergetal (which specifies the size of this array amongst
other things) is set to 6 and never changed.
 

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,717
Messages
2,569,382
Members
44,703
Latest member
FlorianDey

Latest Threads

Top