How to improve my function?

B

Bowlderster

Hi,all.

I produce a function to analysis the test data,which is wave signal, and stored as array a.
I want to figure out how many times it upcrosses zero,which means that when a<0,and a[i+1]>0,
it upcrosses zero one time.I need store the numbers of upcross zero, and the index where it upcrosses
zero, for example, index i(a[i}<0&&a[i+1]>0) and index j(a[j]<0&&a[j+1]>0).Between a and a[j],
there is no upcross zero signal. The maximum and minimum value between a[i+1] and a[j] need to be found,
and a new array is defined as h[n], which is used to store MAX-MIN between a[i+1] and a[j].So the size of
array h should be NUM-1, where NUM is the numbers of upcross zero times.

But now I can not define the array h with the size NUM-1.

The following is my function, please note the pointer indexH in function upzeroH, and the array indexH in
the main function, where I define it with size large enough as row/2.I want it's size just is wavenums.

Would you please give me a hand? Any suggestion will be helpful.

Thank you for your attention.

Bowlderster.




#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<gsl/gsl_sort_double.h>
#include<gsl/gsl_vector.h>

/*Function to figure out upcross zero times
*wavenums----upcross zero times
*indexH---record where upcross zero
*/


int upzeroH(int *indexH,double *inputH,int ninputH)
{
int i,j,nIndex=0;
double *p1,*p2;
double epsilon=0.0000001;
int nUpzero=0;
for(i=0;i<ninputH-1;++i)
{
// printf("i=%i\n",i);
p1=&inputH;
p2=&inputH[i+1];
while(*p1<-(epsilon)&&*p2>=0)
{
*(indexH+nUpzero)=i;
//printf("Here upzero:%i\n",i);
++nUpzero;
*p1=0;
*p2=0;
}
}

int wavenums=nUpzero-1;
return wavenums;
}

//define a strcut to record the H and T
struct waveHT
{
//H_max
double waveheight_max;
//H_1/10
double waveheight_1_10;
//H_1/3
double waveheight_1_3;
//H_average
double waveheight_average;
//T_max
double waveperiod_max;
//T_1/10
double waveperiod_1_10;
//T_1/3
double waveperiod_1_3;
//T_average
double waveperiod_average;
};


//Function to calculate wave height and period
struct waveHT cal_h_t(double *h,size_t n)
{
struct waveHT wave_h_t;
//H_max
double *tmp_hmax;
tmp_hmax=(double*)malloc(sizeof(double));
wave_h_t.waveheight_max=gsl_sort_largest(tmp_hmax,1,h,1,n);
wave_h_t.waveheight_max=*tmp_hmax;
free(tmp_hmax);

//H_1/10 or H_s
double *tmp_hs;
tmp_hs=(double*)malloc(n/3*sizeof(double));

free(tmp_hs);


return wave_h_t;
}


int main(void)
{
int i,j,row=10240,column=3;
int numWaves;
int indexH[row/2];
double a[row];
double dt=0.02;

struct waveHT htest;

for(i=0;i<row;++i)
{
a=sin(-0.2+i*dt);
}

// numWaves=nUpzero(a,row);
numWaves=upzeroH(indexH,a,row);
//printf("There are %i waves \n",numWaves);

// for(i=0;i<numWaves+1;++i)
// printf("%i and Here upcross zero: %i\n",i,*(indexH+i));

// printf("size of indexH %i\n",sizeof(indexH));
double ht[numWaves];

for(i=0;i<numWaves;++i)
{
// printf("space %i\n",indexH[i+1]-indexH);
gsl_vector *v=gsl_vector_alloc(indexH[i+1]-indexH);
for(j=0;j<indexH[i+1]-indexH;++j)
gsl_vector_set(v,j,a[indexH+j]);
ht=gsl_vector_max(v)-gsl_vector_min(v);
// printf("wave height is %g\n",ht);
gsl_vector_free(v);
}

htest=cal_h_t(ht,numWaves);

printf("The largest wave height is %g\n",htest.waveheight_max);

return 0;
}
 
B

Ben Bacarisse

Bowlderster said:
Hi,all.

I produce a function to analysis the test data,which is wave signal,
and stored as array a. I want to figure out how many times it
upcrosses zero,which means that when a<0,and a[i+1]>0, it
upcrosses zero one time.I need store the numbers of upcross zero,
and the index where it upcrosses zero, for example, index
i(a[i}<0&&a[i+1]>0) and index j(a[j]<0&&a[j+1]>0).Between a and
a[j], there is no upcross zero signal. The maximum and minimum value
between a[i+1] and a[j] need to be found, and a new array is defined
as h[n], which is used to store MAX-MIN between a[i+1] and a[j].So
the size of array h should be NUM-1, where NUM is the numbers of
upcross zero times.

But now I can not define the array h with the size NUM-1.


You will have to make two passes though the data or make a guess and
then enlarge the array if you guess too small. You can re-size a
dynamic array using realloc.
int upzeroH(int *indexH,double *inputH,int ninputH)
{
int i,j,nIndex=0;
double *p1,*p2;
double epsilon=0.0000001;
int nUpzero=0;
for(i=0;i<ninputH-1;++i)
{
// printf("i=%i\n",i);
p1=&inputH;
p2=&inputH[i+1];
while(*p1<-(epsilon)&&*p2>=0)
{
*(indexH+nUpzero)=i;


Writing 'indexH[nUpzero] = i;' is more idiomatic in C.
//printf("Here upzero:%i\n",i);
++nUpzero;
*p1=0;
*p2=0;
}

The while is just an 'if' and the pointers are not required:

}

int wavenums=nUpzero-1;
return wavenums;

Mixed code and declarations is a C99 addition. I think 'return
nUpzero - 1;' preferable anyway.
}

//define a strcut to record the H and T
struct waveHT
{
//H_max
double waveheight_max;
//H_1/10
double waveheight_1_10;
//H_1/3
double waveheight_1_3;
//H_average
double waveheight_average;
//T_max
double waveperiod_max;
//T_1/10
double waveperiod_1_10;
//T_1/3
double waveperiod_1_3;
//T_average
double waveperiod_average;
};


//Function to calculate wave height and period
struct waveHT cal_h_t(double *h,size_t n)
{
struct waveHT wave_h_t;
//H_max
double *tmp_hmax;
tmp_hmax=(double*)malloc(sizeof(double));
wave_h_t.waveheight_max=gsl_sort_largest(tmp_hmax,1,h,1,n);
wave_h_t.waveheight_max=*tmp_hmax;
free(tmp_hmax);

You don't *need* malloc just because gsl_sort_largest needs a pointer:

double tmp_hmax;
wave_h_t.waveheight_max = gsl_sort_largest(&tmp_hmax, 1, h, 1, n);
//H_1/10 or H_s
double *tmp_hs;
tmp_hs=(double*)malloc(n/3*sizeof(double));

free(tmp_hs);
???



return wave_h_t;
}


int main(void)
{
int i,j,row=10240,column=3;
int numWaves;
int indexH[row/2];

Here I would use a pointer and malloc a guessed size.
double a[row];
double dt=0.02;

struct waveHT htest;

for(i=0;i<row;++i)
{
a=sin(-0.2+i*dt);
}

// numWaves=nUpzero(a,row);
numWaves=upzeroH(indexH,a,row);


and then pass the size along with a pointer to indexH so upzeroH can
re-allocate the array is if needs to (and change indexH to point to
this new bigger array).

You can avoid passing a 'double **' if you have upzerH return a poiner
to the new, possibly larger, array. I would opt for the 'double **'
route on balance.

<snip> (I did not look at all the code.)
 
C

Charlie Gordon

Bowlderster said:
Hi,all.

I produce a function to analysis the test data,which is wave signal, and
stored as array a.
I want to figure out how many times it upcrosses zero,which means that
when a<0,and a[i+1]>0,
it upcrosses zero one time.I need store the numbers of upcross zero, and
the index where it upcrosses
zero, for example, index i(a[i}<0&&a[i+1]>0) and index
j(a[j]<0&&a[j+1]>0).Between a and a[j],
there is no upcross zero signal. The maximum and minimum value between
a[i+1] and a[j] need to be found,
and a new array is defined as h[n], which is used to store MAX-MIN between
a[i+1] and a[j].So the size of
array h should be NUM-1, where NUM is the numbers of upcross zero times.

But now I can not define the array h with the size NUM-1.

The following is my function, please note the pointer indexH in function
upzeroH, and the array indexH in
the main function, where I define it with size large enough as row/2.I
want it's size just is wavenums.

Would you please give me a hand? Any suggestion will be helpful.

Thank you for your attention.

Bowlderster.

<snip packed cobs of code>

What is wrong with your space bar ?
Your code is unreadable.
I would grade it as F without further study.
 

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

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top