Velocity Reviews > How to improve my function?

# How to improve my function?

Bowlderster
Guest
Posts: n/a

 10-30-2007
Hi,all.

I produce a function to analysis the test data,which is wave signal, and stored as array a[i].
I want to figure out how many times it upcrosses zero,which means that when a[i]<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[i] 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.

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

htest=cal_h_t(ht,numWaves);

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

return 0;
}

Ben Bacarisse
Guest
Posts: n/a

 10-30-2007
Bowlderster <(E-Mail Removed)> writes:

> Hi,all.
>
> I produce a function to analysis the test data,which is wave signal,
> and stored as array a[i]. I want to figure out how many times it
> upcrosses zero,which means that when a[i]<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[i] 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[i];
> 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:

if (inputH[i] < -epsilon && inputH[i + 1] >= 0)
indexH[nUpzero++] = i;

> }
>
> 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[i]=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.)

--
Ben.

Charlie Gordon
Guest
Posts: n/a

 10-30-2007
"Bowlderster" <(E-Mail Removed)> a écrit dans le message de news:
http://www.velocityreviews.com/forums/(E-Mail Removed)...
> Hi,all.
>
> I produce a function to analysis the test data,which is wave signal, and
> stored as array a[i].
> I want to figure out how many times it upcrosses zero,which means that
> when a[i]<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[i] 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 ?
I would grade it as F without further study.

--
Chqrlie.