Ejemplo n.º 1
0
DataTable *
readData (char filename[], char sep, int b_readName, long nmaxvar, long nmaxsample)
{
  DataTable *myData = new DataTable;
  if (!myData)
    {
      fprintf (stderr, "Line %d: Fail to allocate memory.\n", __LINE__);
      exit (EXIT_FAILURE);
      return 0;
    }

  FILE *fid = NULL;

  if ((fid = fopen (filename, "rt")) == NULL)
    {
      fprintf (stderr, "Line %d: Fail to open file.\n", __LINE__);
      exit (EXIT_FAILURE);
      return myData;
    }

  long MAXLINELEN = nmaxsample+1; //+1 for the first row which is the variable names
  long MAXVARNUM = nmaxvar+1; //+1 for the first column which is the classification variable
//  unsigned char *row[MAXVARNUM];

  myData->data = new float[MAXLINELEN * MAXVARNUM];
  if (!myData->data)
    {
      fprintf (stderr, "Line %d: Fail to allocate memory of %d bytes, -- if you don't have or don't need big memory, better set the #MaxVariables and #MaxSamples to a smaller value .\n", __LINE__, MAXLINELEN * MAXVARNUM);
      exit (EXIT_FAILURE);
      return myData;
    }

  long *posfield = new long[MAXVARNUM + 1];	// plus to get the correct number of separation intervals 
  if (!posfield)
    {
      fprintf (stderr, "Line %d: Fail to allocate memory .\n", __LINE__);
      exit (EXIT_FAILURE);
      return 0;
    }

  char *line = NULL;
  size_t len = 0;
  ssize_t nbyteread;

  myData->nsample = 0;
  myData->nvar = 0;
  float *pdata = myData->data;

//  printf ("\ninitial input len=%d\n", len);

  while ((nbyteread = gnu_getline (&line, &len, fid)) != -1) //change on 01/26/2006 for the Mac OS
    {
      if (myData->nsample > MAXLINELEN)
	break;

      //    printf ("Retrieved line of length %u :\n", nbyteread);
      //    printf ("\n%s input len=%d real len=%d\n", line, len, nbyteread);

      // read a line and find all partition intervals

      long ncurfield = 1;	//at least one field in one line
      posfield[0] = -1;		// later one, the start positon will always plus 1, so to get the correct starting location at 0 

      long j = 0;
      while (j < nbyteread)
	{
	  if (line[j] == sep)
	    {
	      ncurfield++;
	      if (ncurfield > MAXVARNUM)
		{
		  fprintf (stderr,
			   "Maximum number of variable %d is attained!\n",
			   MAXVARNUM);
		  break;
		}
	      posfield[ncurfield - 1] = j;
//            printf ("%d ", j);
	    }
	  j++;
	}

      posfield[ncurfield] = nbyteread - 1;	// the end of a line is a '\n' char will wouldn't do any harm if removed

      if (myData->nsample == 0)
	{
	  myData->nvar = ncurfield;
//        printf ("nvar=%d\n", myData->nvar);
	}
      else
	{
	  if (myData->nvar != ncurfield)
	    {
	      fprintf
		(stderr,
		 "Line %d: Read a different number of field: The DATA has error!!!\n",
		 __LINE__);
	      exit (EXIT_FAILURE);
	      return 0;
	    }
//        printf ("ncurfield=%d\n", ncurfield);
	}

      // convert the intervals data in char type as numbers

      const int buflen = 128;
      int intervalLen = 0;
      char tmpbuf[buflen + 1];	// at most 10 char long, thus should be very safe. Add 1 to put '\0'

      if (b_readName)
	{
	  if (myData->nsample == 0)
	    {
	      myData->variableName = new char *[ncurfield];
	      if (!myData->variableName)
		{
		  fprintf (stderr, "Line %d: Fail to allocate memory.\n",
			   __LINE__);
		  exit (EXIT_FAILURE);
		  return 0;
		}

	      for (j = 0; j < ncurfield; j++)
		{
		  intervalLen = posfield[j + 1] - posfield[j] - 1;
		  intervalLen = (intervalLen > buflen) ? buflen : intervalLen;

		  myData->variableName[j] = new char[intervalLen + 1];
		  if (!myData->variableName[j])
		    {
		      fprintf (stderr, "Line %d: Fail to allocate memory.\n",
			       __LINE__);
		      exit (EXIT_FAILURE);
		      return 0;
		    }

		  int tmpj = 0;
		  for (tmpj = 0; tmpj < intervalLen; tmpj++)
		    myData->variableName[j][tmpj] =
		      line[posfield[j] + 1 + tmpj];
		  myData->variableName[j][tmpj] = '\0';
//                printf ("%s\n", myData->variableName[j]);
		}
	    }
	  else
	    {
	      for (j = 0; j < ncurfield; j++)
		{
		  intervalLen = posfield[j + 1] - posfield[j] - 1;
		  intervalLen = (intervalLen > buflen) ? buflen : intervalLen;
		  int tmpj = 0;
		  for (tmpj = 0; tmpj < intervalLen; tmpj++)
		    tmpbuf[tmpj] = line[posfield[j] + 1 + tmpj];
		  tmpbuf[tmpj] = '\0';	//even for the input like ",,,", this is correct to generate the val to be 0
		  double val = atof (tmpbuf);
//                printf ("%s\n", tmpbuf);

		  *pdata++ = val;	//assign the read data
		}
	    }
	}
      else
	{
	  for (j = 0; j < ncurfield; j++)
	    {
	      intervalLen = posfield[j + 1] - posfield[j] - 1;
	      intervalLen = (intervalLen > buflen) ? buflen : intervalLen;
	      int tmpj = 0;
	      for (tmpj = 0; tmpj < intervalLen; tmpj++)
		tmpbuf[tmpj] = line[posfield[j] + 1 + tmpj];
	      tmpbuf[tmpj] = '\0';
	      double val = atof (tmpbuf);
//            printf ("%s\n", tmpbuf);

	      *pdata++ = val;	//assign the read data
	    }
	}
// increase the count of the rows

      myData->nsample++;
    }

  if (b_readName)
    {
      myData->nsample--;	//when the variable name is present, then the total number of samples has only n-1 rows
    }

  if (line)
    free (line);

  if (posfield)
    {
      delete[]posfield;
      posfield = 0;
    }

  return myData;		// if succeed 

}
Ejemplo n.º 2
0
void getlsampthresh(int N, double *t, double *mag, double *sig, double period, int harm_specsigflag, FILE *signalfile, int Nsubharm, int Nharm, double minPer, double thresh, double *ampthresh_scale, double *amp, int use_orig_ls)
{
  /* This routine takes a light curve and a period, it fits a fourier series to the light curve to determine the signal, which is subtracted from the light curve, it then scales the signal and adds it back to the light curve and calculates the lomb-scargle probability at the specified period. It repeats, adjusting the scale until the LS probability is above the thresh-hold at which point the threshhold scaling factor will be returned. If the original light curve does not pass the signal, a negative factor will be returned.

Embedded in this routine is the zbrent algorithm (see Numerical Recipes in C) to find the zero of LS-Prob = thresh.
*/
  double getlsampthresh_func(double amp_scale, int N, double *t, double *mag_orig, double *sig, double *mag_signal, double *mag_tmp, double period, int Nsubharm, int Nharm, double *subharmA, double *subharmB, double *harmA, double *harmB, double fundA, double fundB, double minPer, double thresh, int use_orig_ls);
  int i;
  double *subharmA, *subharmB, *harmA, *harmB, fundA, fundB, meanval, dum1, dum2;
  double *t_tmp, *mag_tmp, *sig_tmp, *mag_signal, *mag_orig, val0, val1;
  int iter;
  double a, b, c, d, e, min1, min2, fa, fb, fc, p, q, r, s, tol1, xm, tol;
  char *line;
  size_t line_size = MAXLEN;
  
  if((t_tmp = (double *) malloc(N * sizeof(double))) == NULL ||
     (mag_tmp = (double *) malloc(N * sizeof(double))) == NULL ||
     (sig_tmp = (double *) malloc(N * sizeof(double))) == NULL ||
     (mag_signal = (double *) malloc(N * sizeof(double))) == NULL ||
     (mag_orig = (double *) malloc(N * sizeof(double))) == NULL ||
     (subharmA = (double *) malloc((Nsubharm + 1) * sizeof(double))) == NULL ||
     (subharmB = (double *) malloc((Nsubharm + 1) * sizeof(double))) == NULL ||
     (harmA = (double *) malloc((Nharm + 1) * sizeof(double))) == NULL ||
     (harmB = (double *) malloc((Nharm + 1) * sizeof(double))) == NULL)
    error(ERR_MEMALLOC);

  /* First Get the signal */
  /* Read the signal in from the file if we're doing that */
  if(harm_specsigflag)
    {
      line = malloc(line_size);
      rewind(signalfile);
      val0 = 0.;
      for(i=0;i<N;i++)
	{
	  gnu_getline(&line,&line_size,signalfile);
	  sscanf(line,"%lf %lf %lf",&dum1,&dum2,&mag_signal[i]);
	  val0 += mag[i];
	}
      val0 = val0 / (double) N;
      for(i=0;i<N;i++)
	{
	  mag_signal[i] -= val0;
	  mag_orig[i] = mag[i] - mag_signal[i];
	}

      fclose(signalfile);
      free(line);
    }
  /* Otherwise fit a fourier series at the period to compute the signal */
  else
    {
      for(i=0;i<N;i++)
	{
	  t_tmp[i] = t[i]; mag_tmp[i] = mag[i]; sig_tmp[i] = sig[i];
	}
      dokillharms(N, t_tmp, mag_tmp, sig_tmp, 1, &period, Nsubharm, Nharm, &subharmA, &subharmB, &harmA, &harmB, &fundA, &fundB, &meanval, 0, NULL, amp, 0, KILLHARM_OUTTYPE_DEFAULT, -1.);
      for(i=0;i<N;i++)
	{
	  mag_signal[i] = mag[i] - mag_tmp[i];
	  mag_orig[i] = mag_tmp[i];
	}
    }

  /* Check to see if no signal still lies above the threshhold, or if the original signal lies below the threshhold */
  val0 = getlsampthresh_func(0., N, t, mag_orig, sig, mag_signal, mag_tmp, period, Nsubharm, Nharm, subharmA, subharmB, harmA, harmB, fundA, fundB, minPer, thresh, use_orig_ls);
  val1 = getlsampthresh_func(1., N, t, mag_orig, sig, mag_signal, mag_tmp, period, Nsubharm, Nharm, subharmA, subharmB, harmA, harmB, fundA, fundB, minPer, thresh, use_orig_ls);
  if(val0 < 0)
    {
      *ampthresh_scale = 0.;
      *amp = (*amp)*(*ampthresh_scale);
      free(t_tmp);
      free(mag_tmp);
      free(sig_tmp);
      free(mag_signal);
      free(mag_orig);
      free(subharmA);
      free(subharmB);
      free(harmA);
      free(harmB);
      return;
    }
  if(val1 > 0)
    {
      *ampthresh_scale = -1.;
      *amp = (*amp)*(*ampthresh_scale);
      free(t_tmp);
      free(mag_tmp);
      free(sig_tmp);
      free(mag_signal);
      free(mag_orig);
      free(subharmA);
      free(subharmB);
      free(harmA);
      free(harmB);
      return;
    }
  a = 0.;
  b = 1.;
  tol = 1.0e-5;

  /* Now start the zbrent loop */
  fa = val0; fb = val1;
  fc = fb;
  for (iter=1; iter<=ITMAX; iter++) {
    if ((fb > 0.0 && fc > 0.0) || (fb < 0.0 && fc < 0.0)) {
      c = a;
      fc = fa;
      e=d=b-a;
    }
    if(fabs(fc) < fabs(fb)) {
      a = b; b = c; c = a; fa = fb; fb = fc; fc = fa;
    }
    tol1 = 2.0*EPS*fabs(b)+0.5*tol;
    xm=0.5*(c-b);
    if (fabs(xm) <= tol1 || fb == 0.0)
      {
	*ampthresh_scale = b;
	*amp = (*amp)*(*ampthresh_scale);
	free(t_tmp);
	free(mag_tmp);
	free(sig_tmp);
	free(mag_signal);
	free(mag_orig);
	free(subharmA);
	free(subharmB);
	free(harmA);
	free(harmB);
	return;
      }
    if (fabs(e) >= tol1 && fabs(fa) > fabs(fb)) {
      s = fb/fa;
      if (a == c) {
	p = 2.0*xm*s;
	q = 1.0 - s;
      } else {
	q = fa/fc;
	r = fb/fc;
	p = s*(2.0*xm*q*(q-r)-(b-a)*(r-1.0));
	q = (q-1.0)*(r-1.0)*(s-1.0);
      }
      if (p > 0.0) q = -q;
      p = fabs(p);
      min1 = 3.0*xm*q - fabs(tol1*q);
      min2 = fabs(e*q);
      if (2.0*p < (min1 < min2 ? min1 : min2)) {
	e=d;
	d=p/q;
      } else {
	d=xm;
	e=d;
      }
    } else {
      d=xm;
      e=d;
    }
    a=b;
    fa=fb;
    if (fabs(d) > tol1)
      b += d;
    else
      b += SIGN(tol1,xm);
    fb = getlsampthresh_func(b, N, t, mag_orig, sig, mag_signal, mag_tmp, period, Nsubharm, Nharm, subharmA, subharmB, harmA, harmB, fundA, fundB, minPer, thresh, use_orig_ls);
  }
  /* Too many iterations - set ampthresh_scale to -2. */
  *ampthresh_scale = -2.;
  *amp = (*amp)*(*ampthresh_scale);
  free(t_tmp);
  free(mag_tmp);
  free(sig_tmp);
  free(mag_signal);
  free(mag_orig);
  free(subharmA);
  free(subharmB);
  free(harmA);
  free(harmB);
  return;
}