Example #1
0
main(int argc, char *argv[])
{
/*
 * Purpose
 * =======
 *
 * The driver program CLINSOLX2.
 *
 * This example illustrates how to use CGSSVX to solve systems repeatedly
 * with the same sparsity pattern of matrix A.
 * In this case, the column permutation vector perm_c is computed once.
 * The following data structures will be reused in the subsequent call to
 * CGSSVX: perm_c, etree
 *
 */
    char           equed[1];
    yes_no_t       equil;
    trans_t        trans;
    SuperMatrix    A, A1, L, U;
    SuperMatrix    B, B1, X;
    NCformat       *Astore;
    NCformat       *Ustore;
    SCformat       *Lstore;
    complex         *a, *a1;
    int            *asub, *xa, *asub1, *xa1;
    int            *perm_r; /* row permutations from partial pivoting */
    int            *perm_c; /* column permutation vector */
    int            *etree;
    void           *work;
    int            info, lwork, nrhs, ldx;
    int            i, j, m, n, nnz;
    complex         *rhsb, *rhsb1, *rhsx, *xact;
    float         *R, *C;
    float         *ferr, *berr;
    float         u, rpg, rcond;
    mem_usage_t    mem_usage;
    superlu_options_t options;
    SuperLUStat_t stat;
    extern void    parse_command_line();

#if ( DEBUGlevel>=1 )
    CHECK_MALLOC("Enter main()");
#endif

    /* Defaults */
    lwork = 0;
    nrhs  = 1;
    equil = YES;
    u     = 1.0;
    trans = NOTRANS;

    /* Set the default input options:
        options.Fact = DOFACT;
        options.Equil = YES;
        options.ColPerm = COLAMD;
        options.DiagPivotThresh = 1.0;
        options.Trans = NOTRANS;
        options.IterRefine = NOREFINE;
        options.SymmetricMode = NO;
        options.PivotGrowth = NO;
        options.ConditionNumber = NO;
        options.PrintStat = YES;
     */
    set_default_options(&options);

    /* Can use command line input to modify the defaults. */
    parse_command_line(argc, argv, &lwork, &u, &equil, &trans);
    options.Equil = equil;
    options.DiagPivotThresh = u;
    options.Trans = trans;

    if ( lwork > 0 ) {
        work = SUPERLU_MALLOC(lwork);
        if ( !work ) {
            ABORT("DLINSOLX: cannot allocate work[]");
        }
    }

    /* Read matrix A from a file in Harwell-Boeing format.*/
    creadhb(&m, &n, &nnz, &a, &asub, &xa);
    if ( !(a1 = complexMalloc(nnz)) ) ABORT("Malloc fails for a1[].");
    if ( !(asub1 = intMalloc(nnz)) ) ABORT("Malloc fails for asub1[].");
    if ( !(xa1 = intMalloc(n+1)) ) ABORT("Malloc fails for xa1[].");
    for (i = 0; i < nnz; ++i) {
        a1[i] = a[i];
        asub1[i] = asub[i];
    }
    for (i = 0; i < n+1; ++i) xa1[i] = xa[i];

    cCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, SLU_NC, SLU_C, SLU_GE);
    Astore = A.Store;
    printf("Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz);

    if ( !(rhsb = complexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsb[].");
    if ( !(rhsb1 = complexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsb1[].");
    if ( !(rhsx = complexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsx[].");
    cCreate_Dense_Matrix(&B, m, nrhs, rhsb, m, SLU_DN, SLU_C, SLU_GE);
    cCreate_Dense_Matrix(&X, m, nrhs, rhsx, m, SLU_DN, SLU_C, SLU_GE);
    xact = complexMalloc(n * nrhs);
    ldx = n;
    cGenXtrue(n, nrhs, xact, ldx);
    cFillRHS(trans, nrhs, xact, ldx, &A, &B);
    for (j = 0; j < nrhs; ++j)
        for (i = 0; i < m; ++i) rhsb1[i+j*m] = rhsb[i+j*m];

    if ( !(perm_c = intMalloc(n)) ) ABORT("Malloc fails for perm_c[].");
    if ( !(perm_r = intMalloc(m)) ) ABORT("Malloc fails for perm_r[].");
    if ( !(etree = intMalloc(n)) ) ABORT("Malloc fails for etree[].");
    if ( !(R = (float *) SUPERLU_MALLOC(A.nrow * sizeof(float))) )
        ABORT("SUPERLU_MALLOC fails for R[].");
    if ( !(C = (float *) SUPERLU_MALLOC(A.ncol * sizeof(float))) )
        ABORT("SUPERLU_MALLOC fails for C[].");
    if ( !(ferr = (float *) SUPERLU_MALLOC(nrhs * sizeof(float))) )
        ABORT("SUPERLU_MALLOC fails for ferr[].");
    if ( !(berr = (float *) SUPERLU_MALLOC(nrhs * sizeof(float))) )
        ABORT("SUPERLU_MALLOC fails for berr[].");

    /* Initialize the statistics variables. */
    StatInit(&stat);

    /* ------------------------------------------------------------
       WE SOLVE THE LINEAR SYSTEM FOR THE FIRST TIME: AX = B
       ------------------------------------------------------------*/
    cgssvx(&options, &A, perm_c, perm_r, etree, equed, R, C,
           &L, &U, work, lwork, &B, &X, &rpg, &rcond, ferr, berr,
           &mem_usage, &stat, &info);

    printf("First system: cgssvx() returns info %d\n", info);

    if ( info == 0 || info == n+1 ) {

        /* This is how you could access the solution matrix. */
        complex *sol = (complex*) ((DNformat*) X.Store)->nzval;

        if ( options.PivotGrowth ) printf("Recip. pivot growth = %e\n", rpg);
        if ( options.ConditionNumber )
            printf("Recip. condition number = %e\n", rcond);
        Lstore = (SCformat *) L.Store;
        Ustore = (NCformat *) U.Store;
        printf("No of nonzeros in factor L = %d\n", Lstore->nnz);
        printf("No of nonzeros in factor U = %d\n", Ustore->nnz);
        printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n);
        printf("FILL ratio = %.1f\n", (float)(Lstore->nnz + Ustore->nnz - n)/nnz);

        printf("L\\U MB %.3f\ttotal MB needed %.3f\n",
               mem_usage.for_lu/1e6, mem_usage.total_needed/1e6);
        if ( options.IterRefine ) {
            printf("Iterative Refinement:\n");
            printf("%8s%8s%16s%16s\n", "rhs", "Steps", "FERR", "BERR");
            for (i = 0; i < nrhs; ++i)
              printf("%8d%8d%16e%16e\n", i+1, stat.RefineSteps, ferr[i], berr[i]);
        }
        fflush(stdout);

    } else if ( info > 0 && lwork == -1 ) {
        printf("** Estimated memory: %d bytes\n", info - n);
    }

    if ( options.PrintStat ) StatPrint(&stat);
    StatFree(&stat);
    Destroy_CompCol_Matrix(&A);
    Destroy_Dense_Matrix(&B);
    if ( lwork >= 0 ) { /* Deallocate storage associated with L and U. */
        Destroy_SuperNode_Matrix(&L);
        Destroy_CompCol_Matrix(&U);
    }

    /* ------------------------------------------------------------
       NOW WE SOLVE ANOTHER LINEAR SYSTEM: A1*X = B1
       ONLY THE SPARSITY PATTERN OF A1 IS THE SAME AS THAT OF A.
       ------------------------------------------------------------*/
    options.Fact = SamePattern;
    StatInit(&stat); /* Initialize the statistics variables. */

    cCreate_CompCol_Matrix(&A1, m, n, nnz, a1, asub1, xa1,
                           SLU_NC, SLU_C, SLU_GE);
    cCreate_Dense_Matrix(&B1, m, nrhs, rhsb1, m, SLU_DN, SLU_C, SLU_GE);

    cgssvx(&options, &A1, perm_c, perm_r, etree, equed, R, C,
           &L, &U, work, lwork, &B1, &X, &rpg, &rcond, ferr, berr,
           &mem_usage, &stat, &info);

    printf("\nSecond system: cgssvx() returns info %d\n", info);

    if ( info == 0 || info == n+1 ) {

        /* This is how you could access the solution matrix. */
        complex *sol = (complex*) ((DNformat*) X.Store)->nzval;

        if ( options.PivotGrowth ) printf("Recip. pivot growth = %e\n", rpg);
        if ( options.ConditionNumber )
            printf("Recip. condition number = %e\n", rcond);
        Lstore = (SCformat *) L.Store;
        Ustore = (NCformat *) U.Store;
        printf("No of nonzeros in factor L = %d\n", Lstore->nnz);
        printf("No of nonzeros in factor U = %d\n", Ustore->nnz);
        printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n);
        printf("L\\U MB %.3f\ttotal MB needed %.3f\n",
               mem_usage.for_lu/1e6, mem_usage.total_needed/1e6);
        if ( options.IterRefine ) {
            printf("Iterative Refinement:\n");
            printf("%8s%8s%16s%16s\n", "rhs", "Steps", "FERR", "BERR");
            for (i = 0; i < nrhs; ++i)
              printf("%8d%8d%16e%16e\n", i+1, stat.RefineSteps, ferr[i], berr[i]);
        }
        fflush(stdout);
    } else if ( info > 0 && lwork == -1 ) {
        printf("** Estimated memory: %d bytes\n", info - n);
    }

    if ( options.PrintStat ) StatPrint(&stat);
    StatFree(&stat);

    SUPERLU_FREE (xact);
    SUPERLU_FREE (etree);
    SUPERLU_FREE (perm_r);
    SUPERLU_FREE (perm_c);
    SUPERLU_FREE (R);
    SUPERLU_FREE (C);
    SUPERLU_FREE (ferr);
    SUPERLU_FREE (berr);
    Destroy_CompCol_Matrix(&A1);
    Destroy_Dense_Matrix(&B1);
    Destroy_Dense_Matrix(&X);
    if ( lwork == 0 ) {
        Destroy_SuperNode_Matrix(&L);
        Destroy_CompCol_Matrix(&U);
    } else if ( lwork > 0 ) {
        SUPERLU_FREE(work);
    }

#if ( DEBUGlevel>=1 )
    CHECK_MALLOC("Exit main()");
#endif
}
    // When an error has occurred, pop elements off the stack until the top
    // state has an error-item. If none is found, the default recovery
    // mode (which is to abort) is activated. 
    //
    // If EOF is encountered without being appropriate for the current state,
    // then the error recovery will fall back to the default recovery mode.
    // (i.e., parsing terminates)
void HTTPTokenizer::errorRecovery()
try
{
    if (d_acceptedTokens__ >= d_requiredTokens__)// only generate an error-
    {                                           // message if enough tokens 
        ++d_nErrors__;                          // were accepted. Otherwise
        error("Syntax error");                  // simply skip input

    }


    // get the error state
    while (not (s_state[top__()][0].d_type & ERR_ITEM))
    {
        pop__();
    }

    // In the error state, lookup a token allowing us to proceed.
    // Continuation may be possible following multiple reductions,
    // but eventuall a shift will be used, requiring the retrieval of
    // a terminal token. If a retrieved token doesn't match, the catch below 
    // will ensure the next token is requested in the while(true) block
    // implemented below:

    int lastToken = d_token__;                  // give the unexpected token a
                                                // chance to be processed
                                                // again.

    pushToken__(_error_);                       // specify _error_ as next token
    push__(lookup(true));                       // push the error state

    d_token__ = lastToken;                      // reactivate the unexpected
                                                // token (we're now in an
                                                // ERROR state).

    bool gotToken = true;                       // the next token is a terminal

    while (true)
    {
        try
        {
            if (s_state[d_state__]->d_type & REQ_TOKEN)
            {
                gotToken = d_token__ == _UNDETERMINED_;
                nextToken();                    // obtain next token
            }
            
            int action = lookup(true);

            if (action > 0)                 // push a new state
            {
                push__(action);
                popToken__();

                if (gotToken)
                {

                    d_acceptedTokens__ = 0;
                    return;
                }
            }
            else if (action < 0)
            {
                // no actions executed on recovery but save an already 
                // available token:
                if (d_token__ != _UNDETERMINED_)
                    pushToken__(d_token__);
 
                                            // next token is the rule's LHS
                reduce__(s_productionInfo[-action]); 
            }
            else
                ABORT();                    // abort when accepting during
                                            // error recovery
        }
        catch (...)
        {
            if (d_token__ == _EOF_)
                ABORT();                    // saw inappropriate _EOF_
                      
            popToken__();                   // failing token now skipped
        }
    }
}
catch (ErrorRecovery__)       // This is: DEFAULT_RECOVERY_MODE
{
    ABORT();
}
/** UNDOCUMENTED */
void
LALUpdateCalibration(
    LALStatus               *status,
    CalibrationFunctions    *output,
    CalibrationFunctions    *input,
    CalibrationUpdateParams *params
    )
{
  const REAL4 tiny = 1e-6;
  COMPLEX8Vector *save;
  COMPLEX8 *R;
  COMPLEX8 *C;
  COMPLEX8 *R0;
  COMPLEX8 *C0;
  COMPLEX8 a;
  COMPLEX8 ab;
  REAL8 epoch;
  REAL8 first_cal;
  REAL8 duration;
  REAL4 dt;
  REAL4 i_r4;
  UINT4 n;
  UINT4 i;
  UINT4 length = 0;
  CHAR  warnMsg[512];

  INITSTATUS(status);
  ATTATCHSTATUSPTR( status );

  /* check input */
  ASSERT( input, status, CALIBRATIONH_ENULL, CALIBRATIONH_MSGENULL );
  ASSERT( input->sensingFunction, status,
      CALIBRATIONH_ENULL, CALIBRATIONH_MSGENULL );
  ASSERT( input->responseFunction, status,
      CALIBRATIONH_ENULL, CALIBRATIONH_MSGENULL );
  ASSERT( input->sensingFunction->data, status,
      CALIBRATIONH_ENULL, CALIBRATIONH_MSGENULL );
  ASSERT( input->responseFunction->data, status,
      CALIBRATIONH_ENULL, CALIBRATIONH_MSGENULL );
  ASSERT( input->sensingFunction->data->data, status,
      CALIBRATIONH_ENULL, CALIBRATIONH_MSGENULL );
  ASSERT( input->responseFunction->data->data, status,
      CALIBRATIONH_ENULL, CALIBRATIONH_MSGENULL );
  n = input->sensingFunction->data->length;
  ASSERT( (int)n > 0, status, CALIBRATIONH_ESIZE, CALIBRATIONH_MSGESIZE );
  ASSERT( input->responseFunction->data->length == n, status,
      CALIBRATIONH_ESZMM, CALIBRATIONH_MSGESZMM );

  /* check output */
  ASSERT( output, status, CALIBRATIONH_ENULL, CALIBRATIONH_MSGENULL );
  ASSERT( output->sensingFunction, status,
      CALIBRATIONH_ENULL, CALIBRATIONH_MSGENULL );
  ASSERT( output->responseFunction, status,
      CALIBRATIONH_ENULL, CALIBRATIONH_MSGENULL );
  ASSERT( output->sensingFunction->data, status,
      CALIBRATIONH_ENULL, CALIBRATIONH_MSGENULL );
  ASSERT( output->responseFunction->data, status,
      CALIBRATIONH_ENULL, CALIBRATIONH_MSGENULL );
  ASSERT( output->sensingFunction->data->data, status,
      CALIBRATIONH_ENULL, CALIBRATIONH_MSGENULL );
  ASSERT( output->responseFunction->data->data, status,
      CALIBRATIONH_ENULL, CALIBRATIONH_MSGENULL );
  ASSERT( output->sensingFunction->data->length == n, status,
      CALIBRATIONH_ESZMM, CALIBRATIONH_MSGESZMM );
  ASSERT( output->responseFunction->data->length == n, status,
      CALIBRATIONH_ESZMM, CALIBRATIONH_MSGESZMM );

  /* check params */
  ASSERT( params, status, CALIBRATIONH_ENULL, CALIBRATIONH_MSGENULL );
  ASSERT( params->sensingFactor, status,
      CALIBRATIONH_ENULL, CALIBRATIONH_MSGENULL );
  ASSERT( params->openLoopFactor, status,
      CALIBRATIONH_ENULL, CALIBRATIONH_MSGENULL );
  ASSERT( params->sensingFactor->deltaT, status,
      CALIBRATIONH_ENULL, CALIBRATIONH_MSGENULL );
  ASSERT( params->sensingFactor->data, status,
      CALIBRATIONH_ENULL, CALIBRATIONH_MSGENULL );
  ASSERT( params->openLoopFactor->data, status,
      CALIBRATIONH_ENULL, CALIBRATIONH_MSGENULL );
  ASSERT( params->sensingFactor->data->data, status,
      CALIBRATIONH_ENULL, CALIBRATIONH_MSGENULL );
  ASSERT( params->openLoopFactor->data->data, status,
      CALIBRATIONH_ENULL, CALIBRATIONH_MSGENULL );
  ASSERT( params->openLoopFactor->data->length ==
      params->sensingFactor->data->length, status,
      CALIBRATIONH_ESZMM, CALIBRATIONH_MSGESZMM );

  R0 = input->responseFunction->data->data;
  C0 = input->sensingFunction->data->data;
  R = output->responseFunction->data->data;
  C = output->sensingFunction->data->data;

  save = output->responseFunction->data;
  output->responseFunction = input->responseFunction;
  output->responseFunction->data = save;
  output->responseFunction->epoch = params->epoch;

  save = output->sensingFunction->data;
  output->sensingFunction = input->sensingFunction;
  output->sensingFunction->data = save;
  output->sensingFunction->epoch = params->epoch;

  /* locate correct values of a and ab */
  epoch = XLALGPSGetREAL8(&(params->epoch));
  first_cal = XLALGPSGetREAL8(&(params->sensingFactor->epoch));
  duration = XLALGPSGetREAL8(&(params->duration));

  dt = epoch - first_cal;

  /* find the first point at or before the requested time */
  if ( (i_r4 = floor( dt / params->sensingFactor->deltaT ) ) < 0 )
  {
    ABORT( status, CALIBRATIONH_ETIME, CALIBRATIONH_MSGETIME );
  }
  else
  {
    i = (UINT4) i_r4;
  }

  /* compute the sum of the calibration factors */
  a = ab = 0;
  length = 0;
  do
  {
    COMPLEX8 this_a;
    COMPLEX8 this_ab;

    if ( i > params->sensingFactor->data->length - 1 )
    {
      ABORT( status, CALIBRATIONH_ETIME, CALIBRATIONH_MSGETIME );
    }

    this_a = params->sensingFactor->data->data[i];
    this_ab = params->openLoopFactor->data->data[i];

    /* JC: I CHANGED THE LOGIC HERE TO WHAT I THOUGHT IT SHOULD BE! */
    if ( ( fabs( creal(this_a) ) < tiny && fabs( cimag(this_a) ) < tiny ) ||
         ( fabs( creal(this_ab) ) < tiny && fabs( cimag(this_ab) ) < tiny ) )
    {
      /* this is a hack for the broken S2 calibration frame data */
      if ( (params->epoch.gpsSeconds >= CAL_S2START) &&
          (params->epoch.gpsSeconds < CAL_S2END ) )
      {
        /* if the zero is during S2 print a warning... */
        snprintf( warnMsg, XLAL_NUM_ELEM(warnMsg),
            "Zero calibration factors found during S2 at GPS %10.9f",
            first_cal + (REAL8) i * params->sensingFactor->deltaT );
        LALWarning( status, warnMsg );
      }
      else
      {
        /* ...or abort if we are outside S2 */
        snprintf( warnMsg, XLAL_NUM_ELEM(warnMsg),
            "Zero calibration factor found at GPS %10.9f",
            first_cal + (REAL8) i * params->sensingFactor->deltaT );
        LALWarning( status, warnMsg );
        ABORT( status, CALIBRATIONH_EZERO, CALIBRATIONH_MSGEZERO );
      }
    }
    else
    {
      /* increment the count of factors if we are adding a non-zero value */
      ++length;
    }

    /* add this value to the sum */
    a += this_a;
    ab += this_ab;

    /* increment the calibration factor index */
    ++i;
  }
  while ( (first_cal + (REAL8) i * params->sensingFactor->deltaT) <
      (epoch + duration) );

  /* if all the calibration factors are zero the abort */
  if ( ! length ||
      (fabs( creal(a) ) < tiny && fabs( cimag(a) ) < tiny) ||
      (fabs( creal(ab) ) < tiny && fabs( cimag(ab) ) < tiny) )
  {
    snprintf( warnMsg, XLAL_NUM_ELEM(warnMsg),
        "Got %d calibration samples\nalpha and/or beta are zero:\n"
        "Re a = %e\tIm a = %e\nRe ab = %e\tIm ab = %e",
        length, creal(a), cimag(a), creal(ab), cimag(ab) );
    LALWarning( status, warnMsg );
    ABORT( status, CALIBRATIONH_EZERO, CALIBRATIONH_MSGEZERO );
  }

  /* compute the mean of the calibration factors from the sum */
  a /= length;
  ab /= length;

  /* return the used values of alpha and alphabeta */
  params->alpha = a;
  params->alphabeta = ab;
  snprintf( warnMsg, XLAL_NUM_ELEM(warnMsg),
      "Got %d calibration samples\n"
      "Re a = %e\tIm a = %e\nRe ab = %e\tIm ab = %e",
      length, creal(a), cimag(a), creal(ab), cimag(ab) );
  LALInfo( status, warnMsg );

  for ( i = 0; i < n; ++i )
  {
    C[i] = a * C0[i];
    R[i] = (ab * (C0[i] * R0[i] - 1.0) + 1.0) / C[i];
  }
  DETATCHSTATUSPTR( status );
  RETURN( status );
}
/** UNDOCUMENTED */
void
LALResponseConvert(
    LALStatus               *status,
    COMPLEX8FrequencySeries *output,
    COMPLEX8FrequencySeries *input
    )
{
  LALUnit unitOne;
  LALUnit unitTwo;
  UINT4 i;
  INT4 inv;
  INT4 fac;
  INT4 bad;

  INITSTATUS(status);
  ATTATCHSTATUSPTR( status );

  output->epoch = input->epoch;

  /*
   * Interpolate to requested frequencies.
   * Just do linear interpolation of real and imag components.
   */
  for ( i = 0; i < output->data->length; ++i )
  {
    REAL4 x;
    UINT4 j;
    x = i * output->deltaF / input->deltaF;
    j = floor( x );
    if ( j > input->data->length - 2 )
      j = input->data->length - 2;
    x -= j;
    output->data->data[i] = input->data->data[j]
      + x * ( input->data->data[j+1] - input->data->data[j] );
  }


  /*
   * Use output units to figure out:
   *   1. Whether we want strain/ct or ct/strain
   *   2. Overall (power of ten) factor to apply.
   */

  /* determine if units need to be inverted or not (or if they are bad) */
  XLALUnitNormalize( &output->sampleUnits );
  XLALUnitNormalize( &input->sampleUnits );
  unitOne = output->sampleUnits;
  unitTwo = input->sampleUnits;

  bad = 0;
  inv = -1;
  for ( i = 0; i < LALNumUnits; ++i )
  {
    if ( unitOne.unitDenominatorMinusOne[i] != unitTwo.unitDenominatorMinusOne[i] )
    {
      bad = 1;
      break;
    }
    if ( unitOne.unitNumerator[i] == unitTwo.unitNumerator[i] )
    {
      if ( unitOne.unitNumerator[i] ) /* if this unit exists */
      {
        inv = 0; /* we don't need to invert */
        if ( inv == 1 ) /* error: some units need to be inverted, others not */
        {
          bad = 1;
          break;
        }
      }
    }
    else
    {
      if ( unitOne.unitNumerator[i] == -unitTwo.unitNumerator[i] )
      {
        /* this unit needs to be inverted */
        inv = 1;
      }
      else /* error: output units not equal to input or inverse of input */
      {
        bad = 1;
        break;
      }
    }
  }
  if ( bad ) /* units were bad: abort */
  {
    ABORT( status, CALIBRATIONH_EUNIT, CALIBRATIONH_MSGEUNIT );
  }

  /* determine if there is a scale factor that needs to be applied */
  fac = unitOne.powerOfTen - ( inv ? -unitTwo.powerOfTen : unitTwo.powerOfTen );

  /* perform conversion(s) */

  if ( inv ) /* invert data */
  {
    for ( i = 0; i < output->data->length; ++i )
    {
      output->data->data[i] = 1.0 / output->data->data[i];
    }
  }

  if ( fac ) /* scale data */
  {
    REAL4 scale = pow( 10.0, -fac );
    for ( i = 0; i < output->data->length; ++i )
    {
      output->data->data[i] *= scale;
    }
  }

  DETATCHSTATUSPTR( status );
  RETURN( status );
}
Example #5
0
char inputfile::ReadLetter(truth AbortOnEOF)
{
  for(int Char = fgetc(Buffer); !feof(Buffer); Char = fgetc(Buffer))
  {
    if(isalpha(Char) || isdigit(Char))
      return Char;

    if(ispunct(Char))
    {
      if(Char == '/')
      {
	if(!feof(Buffer))
	{
	  Char = fgetc(Buffer);

	  if(Char == '*')
	  {
	    long StartPos = TellPos();
	    int OldChar = 0, CommentLevel = 1;

	    for(;;)
	    {
	      if(feof(Buffer))
		ABORT("Unterminated comment in file %s, "
		      "beginning at line %ld!",
		      FileName.CStr(), TellLineOfPos(StartPos));

	      Char = fgetc(Buffer);

	      if(OldChar != '*' || Char != '/')
	      {
		if(OldChar != '/' || Char != '*')
		  OldChar = Char;
		else
		{
		  ++CommentLevel;
		  OldChar = 0;
		}
	      }
	      else
	      {
		if(!--CommentLevel)
		  break;
		else
		  OldChar = 0;
	      }
	    }

	    continue;
	  }
	  else
	    ungetc(Char, Buffer);
	}

	return '/';
      }

      return Char;
    }
  }

  if(AbortOnEOF)
    ABORT("Unexpected end of file %s!", FileName.CStr());

  return 0;
}
Example #6
0
int inputfile::HandlePunct(festring& String, int Char, int Mode)
{
  if(Char == '/')
  {
    if(!feof(Buffer))
    {
      Char = fgetc(Buffer);

      if(Char == '*')
      {
	long StartPos = TellPos();
	int OldChar = 0, CommentLevel = 1;

	for(;;)
	{
	  if(feof(Buffer))
	    ABORT("Unterminated comment in file %s, beginning at line %ld!",
		  FileName.CStr(), TellLineOfPos(StartPos));

	  Char = fgetc(Buffer);

	  if(OldChar != '*' || Char != '/')
	  {
	    if(OldChar != '/' || Char != '*')
	      OldChar = Char;
	    else
	    {
	      ++CommentLevel;
	      OldChar = 0;
	    }
	  }
	  else
	  {
	    if(!--CommentLevel)
	      break;
	    else
	      OldChar = 0;
	  }
	}

	return PUNCT_CONTINUE;
      }
      else
      {
	ungetc(Char, Buffer);
	clearerr(Buffer);
      }
    }

    if(Mode)
      ungetc('/', Buffer);
    else
      String << '/';

    return PUNCT_RETURN;
  }

  if(Mode)
  {
    ungetc(Char, Buffer);
    return PUNCT_RETURN;
  }

  if(Char == '"')
  {
    long StartPos = TellPos();
    int OldChar = 0;

    for(;;)
    {
      if(feof(Buffer))
	ABORT("Unterminated string in file %s, beginning at line %ld!",
	      FileName.CStr(), TellLineOfPos(StartPos));

      Char = fgetc(Buffer);

      if(Char != '"')
      {
	String << char(Char);
	OldChar = Char;
      }
      else if(OldChar == '\\')
      {
	String[String.GetSize() - 1] = '"';
	OldChar = 0;
      }
      else
	return PUNCT_RETURN;
    }
  }

  String << char(Char);
  return PUNCT_RETURN;
}
Example #7
0
void
LALCreateTwoIFOCoincListEllipsoid(
    LALStatus                  *status,
    CoincInspiralTable        **coincOutput,
    SnglInspiralTable          *snglInput,
    InspiralAccuracyList       *accuracyParams
    )

{
  INT8                          currentTriggerNS[2];
  CoincInspiralTable           *coincHead = NULL;
  CoincInspiralTable           *thisCoinc = NULL;
  INT4                          numEvents = 0;
  INT8                          maxTimeDiff = 0;
  TriggerErrorList             *errorListHead = NULL;
  TriggerErrorList             UNUSED *thisErrorList = NULL;
  TriggerErrorList             *currentError[2];
  fContactWorkSpace            *workSpace;
  REAL8                        timeError = 0.0;


  INITSTATUS(status);
  ATTATCHSTATUSPTR( status );

  ASSERT( snglInput, status,
      LIGOMETADATAUTILSH_ENULL, LIGOMETADATAUTILSH_MSGENULL );
  ASSERT( coincOutput, status,
      LIGOMETADATAUTILSH_ENULL, LIGOMETADATAUTILSH_MSGENULL );
  ASSERT( ! *coincOutput, status,
      LIGOMETADATAUTILSH_ENNUL, LIGOMETADATAUTILSH_MSGENNUL );

  memset( currentTriggerNS, 0, 2 * sizeof(INT8) );

  /* Loop through triggers and assign each of them an error ellipsoid */
  errorListHead = XLALCreateTriggerErrorList( snglInput, accuracyParams->eMatch, &timeError );
  if ( !errorListHead )
  {
    ABORTXLAL( status );
  }

  /* Initialise the workspace for ellipsoid overlaps */
  workSpace = XLALInitFContactWorkSpace( 3, NULL, NULL, gsl_min_fminimizer_brent, 1.0e-2 );
  if (!workSpace)
  {
    XLALDestroyTriggerErrorList( errorListHead );
    ABORTXLAL( status );
  }

  /* calculate the maximum time delay
   * set it equal to 2 * worst IFO timing accuracy plus
   * light travel time for earths diameter
   * (detectors cant be further apart than this) */

  maxTimeDiff = (INT8) (1e9 * 2.0 * timeError);
  maxTimeDiff += (INT8) ( 1e9 * 2 * LAL_REARTH_SI / LAL_C_SI );

  for ( currentError[0] = errorListHead; currentError[0]->next;
      currentError[0] = currentError[0]->next)
  {

    /* calculate the time of the trigger */
    currentTriggerNS[0] = XLALGPSToINT8NS(
                 &(currentError[0]->trigger->end_time) );

    /* set next trigger for comparison */
    currentError[1] = currentError[0]->next;
    currentTriggerNS[1] = XLALGPSToINT8NS(
                 &(currentError[1]->trigger->end_time) );

    while ( (currentTriggerNS[1] - currentTriggerNS[0]) < maxTimeDiff )
    {

      INT2 match;

      /* test whether we have coincidence */
      match = XLALCompareInspiralsEllipsoid( currentError[0],
                 currentError[1], workSpace, accuracyParams );
      if ( match == XLAL_FAILURE )
      {
        /* Error in the comparison function */
        XLALDestroyTriggerErrorList( errorListHead );
        XLALFreeFContactWorkSpace( workSpace );
        ABORTXLAL( status );
      }

      /* Check whether the event was coincident */
      if ( match )
      {
#if 0
        REAL8 etp = XLALCalculateEThincaParameter( currentError[0]->trigger,  currentError[1]->trigger, accuracyParams );
#endif
        /* create a 2 IFO coinc and store */
        if ( ! coincHead  )
        {
          coincHead = thisCoinc = (CoincInspiralTable *)
            LALCalloc( 1, sizeof(CoincInspiralTable) );
        }
        else
        {
          thisCoinc = thisCoinc->next = (CoincInspiralTable *)
            LALCalloc( 1, sizeof(CoincInspiralTable) );
        }
        if ( !thisCoinc )
        {
          /* Error allocating memory */
          thisCoinc = coincHead;
          while ( thisCoinc )
          {
            coincHead = thisCoinc->next;
            LALFree( thisCoinc );
            thisCoinc = coincHead;
          }
          XLALDestroyTriggerErrorList( errorListHead );
          XLALFreeFContactWorkSpace( workSpace );
          ABORT( status, LAL_NOMEM_ERR, LAL_NOMEM_MSG );
        }

        /* Add the two triggers to the coinc */
        LALAddSnglInspiralToCoinc( status->statusPtr, &thisCoinc,
            currentError[0]->trigger );
        LALAddSnglInspiralToCoinc( status->statusPtr, &thisCoinc,
            currentError[1]->trigger );

        ++numEvents;

      }

      /* scroll on to the next sngl inspiral */

      if ( (currentError[1] = currentError[1]->next) )
      {
        currentTriggerNS[1] = XLALGPSToINT8NS( &(currentError[1]->trigger->end_time) );
      }
      else
      {
        LALInfo(status, "Second trigger has reached end of list");
        break;
      }
    }
  }

  *coincOutput = coincHead;

  /* Free all the memory allocated for the ellipsoid overlap */
  thisErrorList = errorListHead;
  XLALDestroyTriggerErrorList( errorListHead );
  XLALFreeFContactWorkSpace( workSpace );

  DETATCHSTATUSPTR (status);
  RETURN (status);
}
Example #8
0
outputfile::outputfile(const festring& FileName, truth AbortOnErr)
: Buffer(fopen(FileName.CStr(), "wb")), FileName(FileName)
{
  if(AbortOnErr && !IsOpen())
    ABORT("Can't open %s for output!", FileName.CStr());
}
Example #9
0
/* Create the distributed modified sparse row (MSR) matrix: bindx/val.
 * For a submatrix of size m-by-n, the MSR arrays are as follows:
 *    bindx[0]      = m + 1
 *    bindx[0..m]   = pointer to start of each row
 *    bindx[ks..ke] = column indices of the off-diagonal nonzeros in row k,
 *                    where, ks = bindx[k], ke = bindx[k+1]-1
 *    val[k]        = A(k,k), k < m, diagonal elements
 *    val[m]        = not used
 *    val[ki]       = A(k, bindx[ki]), where ks <= ki <= ke
 * Both arrays are of length nnz + 1.
 */
static void zcreate_msr_matrix
(
 SuperMatrix *A,       /* Matrix A permuted by columns (input).
			  The type of A can be:
			  Stype = SLU_NCP; Dtype = SLU_Z; Mtype = SLU_GE. */
 int_t update[],       /* input (local) */
 int_t N_update,       /* input (local) */
 doublecomplex **val,         /* output */
 int_t **bindx         /* output */
)
{
    int hi, i, irow, j, k, lo, n, nnz_local, nnz_diag;
    NCPformat *Astore;
    doublecomplex *nzval;
    int_t *rowcnt;
    doublecomplex zero = {0.0, 0.0};
    
    if ( !N_update ) return;

    n = A->ncol;
    Astore = A->Store;
    nzval = Astore->nzval;

    /* One pass of original matrix A to count nonzeros of each row. */
    if ( !(rowcnt = (int_t *) intCalloc_dist(N_update)) )
	ABORT("Malloc fails for rowcnt[]");
    lo = update[0];
    hi = update[N_update-1];
    nnz_local = 0;
    nnz_diag = 0;
    for (j = 0; j < n; ++j) {
	for (i = Astore->colbeg[j]; i < Astore->colend[j]; ++i) {
	    irow = Astore->rowind[i];
	    if ( irow >= lo && irow <= hi ) {
		if ( irow != j ) /* Exclude diagonal */
		    ++rowcnt[irow - lo];
		else ++nnz_diag; /* Count nonzero diagonal entries */
		++nnz_local;
	    }
	}
    }

    /* Add room for the logical diagonal zeros which are not counted
       in nnz_local. */
    nnz_local += (N_update - nnz_diag);

    /* Allocate storage for bindx[] and val[]. */
    if ( !(*val = (doublecomplex *) doublecomplexMalloc_dist(nnz_local+1)) )
	ABORT("Malloc fails for val[]");
    for (i = 0; i < N_update; ++i) (*val)[i] = zero; /* Initialize diagonal */
    if ( !(*bindx = (int_t *) SUPERLU_MALLOC((nnz_local+1) * sizeof(int_t))) )
	ABORT("Malloc fails for bindx[]");

    /* Set up row pointers. */
    (*bindx)[0] = N_update + 1;
    for (j = 1; j <= N_update; ++j) {
	(*bindx)[j] = (*bindx)[j-1] + rowcnt[j-1];
	rowcnt[j-1] = (*bindx)[j-1];
    }

    /* One pass of original matrix A to fill in matrix entries. */
    for (j = 0; j < n; ++j) {
	for (i = Astore->colbeg[j]; i < Astore->colend[j]; ++i) {
	    irow = Astore->rowind[i];
	    if ( irow >= lo && irow <= hi ) {
		if ( irow == j ) /* Diagonal */
		    (*val)[irow - lo] = nzval[i];
		else {
		    irow -= lo;
		    k = rowcnt[irow];
		    (*bindx)[k] = j;
		    (*val)[k] = nzval[i];
		    ++rowcnt[irow];
		}
	    }
	}
    }

    SUPERLU_FREE(rowcnt);
}
Example #10
0
int pzgsmv_AXglobal_setup
(
 SuperMatrix *A,       /* Matrix A permuted by columns (input).
			  The type of A can be:
			  Stype = SLU_NCP; Dtype = SLU_Z; Mtype = SLU_GE. */
 Glu_persist_t *Glu_persist, /* input */
 gridinfo_t *grid,     /* input */
 int_t *m,             /* output */
 int_t *update[],      /* output */
 doublecomplex *val[],        /* output */
 int_t *bindx[],       /* output */
 int_t *mv_sup_to_proc /* output */
 )
{
    int n;
    int input_option;
    int N_update;    /* Number of variables updated on this process (output) */
    int iam = grid->iam;
    int nprocs = grid->nprow * grid->npcol;
    int_t *xsup = Glu_persist->xsup;
    int_t *supno = Glu_persist->supno;
    int_t nsupers;
    int i, nsup, p, t1, t2, t3;


    /* Initialize the list of global indices.
     * NOTE: the list of global indices must be in ascending order.
     */
    n = A->nrow;
    input_option = SUPER_LINEAR;
    nsupers = supno[n-1] + 1;

#if ( DEBUGlevel>=2 )
    if ( !iam ) {
	PrintInt10("xsup", supno[n-1]+1, xsup);
	PrintInt10("supno", n, supno);
    }
#endif

    if ( input_option == SUPER_LINEAR ) { /* Block partitioning based on
					     individual rows.  */
	/* Figure out mv_sup_to_proc[] on all processes. */
	for (p = 0; p < nprocs; ++p) {
	    t1 = n / nprocs;       /* Number of rows */
	    t2 = n - t1 * nprocs;  /* left-over, which will be assigned
				      to the first t2 processes.  */
	    if ( p >= t2 ) t2 += (p * t1); /* Starting row number */
	    else { /* First t2 processes will get one more row. */
 	        ++t1;              /* Number of rows. */
		t2 = p * t1;       /* Starting row. */
	    }
	    /* Make sure the starting and ending rows are at the
	       supernode boundaries. */
	    t3 = t2 + t1;      /* Ending row. */
	    nsup = supno[t2];
	    if ( t2 > xsup[nsup] ) { /* Round up the starting row. */
		t1 -= xsup[nsup+1] - t2;
		t2 = xsup[nsup+1];
	    }
	    nsup = supno[t3];
	    if ( t3 > xsup[nsup] ) /* Round up the ending row. */
		t1 += xsup[nsup+1] - t3;
	    t3 = t2 + t1 - 1;
	    if ( t1 ) {
		for (i = supno[t2]; i <= supno[t3]; ++i) {
		    mv_sup_to_proc[i] = p;
#if ( DEBUGlevel>=3 )
		    if ( mv_sup_to_proc[i] == p-1 ) {
			fprintf(stderr, 
				"mv_sup_to_proc conflicts at supno %d\n", i);
			exit(-1);
		    }
#endif
		}
	    }
	    
	    if ( iam == p ) {
		N_update = t1;
		if ( N_update ) {
		    if ( !(*update = intMalloc_dist(N_update)) )
			ABORT("Malloc fails for update[]");
		}
		for (i = 0; i < N_update; ++i) (*update)[i] = t2 + i;
#if ( DEBUGlevel>=3 )
		printf("(%2d) N_update = %4d\t"
		       "supers %4d to %4d\trows %4d to %4d\n",
		       iam, N_update, supno[t2], supno[t3], t2, t3);
#endif
	    }
	} /* for p ... */
    } else if ( input_option == SUPER_BLOCK ) { /* Block partitioning based on
						   individual supernodes.  */
	/* This may cause bad load balance, because the blocks are usually
	   small in the beginning and large toward the end.   */
	t1 = nsupers / nprocs;
	t2 = nsupers - t1 * nprocs; /* left-over */
	if ( iam >= t2 ) t2 += (iam * t1);
	else {
	    ++t1;          /* Number of blocks. */
	    t2 = iam * t1; /* Starting block. */
	}
	N_update = xsup[t2+t1] - xsup[t2];
	if ( !(*update = intMalloc_dist(N_update)) )
	    ABORT("Malloc fails for update[]");
	for (i = 0; i < N_update; ++i) (*update)[i] = xsup[t2] + i;
    }


    /* Create an MSR matrix in val/bindx to be used by pdgsmv(). */
    zcreate_msr_matrix(A, *update, N_update, val, bindx);

#if ( DEBUGlevel>=2 )
    PrintInt10("mv_sup_to_proc", nsupers, mv_sup_to_proc);
    zPrintMSRmatrix(N_update, *val, *bindx, grid);
#endif

    *m = N_update;
    return 0;
} /* PZGSMV_AXglobal_SETUP */
Example #11
0
int main ( int argc, char *argv[] )

/**********************************************************************/
/*
  Purpose:

    SUPER_LU_S2 solves a symmetric sparse system read from a file.

  Discussion:

    The sparse matrix is stored in a file using the Harwell-Boeing
    sparse matrix format.  The file should be assigned to the standard
    input of this program.  For instance, if the matrix is stored
    in the file "g10_rua.txt", the execution command might be:

      super_lu_s2 < g10_rua.txt

  Modified:

    25 April 2004

  Reference:

    James Demmel, John Gilbert, Xiaoye Li,
    SuperLU Users's Guide,
    Sections 1 and 2.

  Local parameters:

    SuperMatrix L, the computed L factor.

    int *perm_c, the column permutation vector.

    int *perm_r, the row permutations from partial pivoting.

    SuperMatrix U, the computed U factor.
*/
{
  SuperMatrix A;
  NCformat *Astore;
  float *a;
  int *asub;
  SuperMatrix B;
  int info;
  SuperMatrix L;
  int ldx;
  SCformat *Lstore;
  int m;
  mem_usage_t mem_usage;
  int n;
  int nnz;
  int nrhs;
  superlu_options_t options;
  int *perm_c;
  int *perm_r;
  float *rhs;
  float *sol;
  SuperLUStat_t stat;
  SuperMatrix U;
  NCformat *Ustore;
  int *xa;
  float *xact;
/*
  Say hello.
*/
  printf ( "\n" );
  printf ( "SUPER_LU_S2:\n" );
  printf ( "  Read a symmetric sparse matrix A from standard input,\n");
  printf ( "  stored in Harwell-Boeing Sparse Matrix format.\n" );
  printf ( "\n" );
  printf ( "  Solve a linear system A * X = B.\n" );
/* 
  Set the default input options:
  options.Fact = DOFACT;
  options.Equil = YES;
  options.ColPerm = COLAMD;
  options.DiagPivotThresh = 1.0;
  options.Trans = NOTRANS;
  options.IterRefine = NOREFINE;
  options.SymmetricMode = NO;
  options.PivotGrowth = NO;
  options.ConditionNumber = NO;
  options.PrintStat = YES;
*/
  set_default_options ( &options );
/* 
  Now we modify the default options to use the symmetric mode. 
*/
  options.SymmetricMode = YES;
  options.ColPerm = MMD_AT_PLUS_A;
  options.DiagPivotThresh = 0.001;
/* 
  Read the matrix in Harwell-Boeing format. 
*/
  sreadhb ( &m, &n, &nnz, &a, &asub, &xa );
/*
  Create storage for a compressed column matrix.
*/
  sCreate_CompCol_Matrix ( &A, m, n, nnz, a, asub, xa, SLU_NC, SLU_S, SLU_GE );
  Astore = A.Store;

  printf ( "\n" );
  printf ( "  Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz );
/*
  Set up the right hand side.
*/  
  nrhs = 1;
  rhs = floatMalloc ( m * nrhs );
  if ( !rhs ) 
  {
    ABORT ( " Malloc fails for rhs[]." );
  }

  sCreate_Dense_Matrix ( &B, m, nrhs, rhs, m, SLU_DN, SLU_S, SLU_GE );
  xact = floatMalloc ( n * nrhs );
  if ( !xact ) 
  {
    ABORT ( " Malloc fails for rhs[]." );
  }
  ldx = n;
  sGenXtrue ( n, nrhs, xact, ldx );
  sFillRHS ( options.Trans, nrhs, xact, ldx, &A, &B );

  perm_c = intMalloc ( n );
  if ( !perm_c ) 
  {
    ABORT ( "Malloc fails for perm_c[]." );
  }

  perm_r = intMalloc ( m );
  if ( !perm_r )
  {
    ABORT ( "Malloc fails for perm_r[]." );
  }
/* 
  Initialize the statistics variables. 
*/
  StatInit ( &stat );
/*
  Call SGSSV to factor the matrix and solve the linear system.
*/
  sgssv ( &options, &A, perm_c, perm_r, &L, &U, &B, &stat, &info );
    
  if ( info == 0 )
  {
/* 
  To conveniently access the solution matrix, you need to get a pointer to it. 
*/
    sol = (float*) ((DNformat*) B.Store)->nzval; 

/* 
  Compute the infinity norm of the error. 
*/
    sinf_norm_error ( nrhs, &B, xact );

    Lstore = (SCformat *) L.Store;
    Ustore = (NCformat *) U.Store;

    printf ( "\n" );
    printf ( "  Number of nonzeros in factor L = %d\n", Lstore->nnz );
    printf ( "  Number of nonzeros in factor U = %d\n", Ustore->nnz );
    printf ( "  Number of nonzeros in L+U = %d\n", 
      Lstore->nnz + Ustore->nnz - n );
	
    sQuerySpace ( &L, &U, &mem_usage );

    printf ( "\n" );
    printf ( "  L\\U MB %.3f\ttotal MB needed %.3f\texpansions %d\n",
      mem_usage.for_lu/1e6, mem_usage.total_needed/1e6,
      mem_usage.expansions);
  } 
  else
  {
    printf ( "\n" );
    printf ( "  SGSSV error returns INFO= %d\n", info );

    if ( info <= n ) 
    {
      sQuerySpace ( &L, &U, &mem_usage );

      printf ( "\n" );
      printf ("  L\\U MB %.3f\ttotal MB needed %.3f\texpansions %d\n",
        mem_usage.for_lu/1e6, mem_usage.total_needed/1e6,
        mem_usage.expansions );
    }
  }

  if ( options.PrintStat ) 
  {
    StatPrint ( &stat );
  }
  StatFree ( &stat );
/*
  Free the memory.
*/
  SUPERLU_FREE ( rhs );
  SUPERLU_FREE ( xact );
  SUPERLU_FREE ( perm_r );
  SUPERLU_FREE ( perm_c );
  Destroy_CompCol_Matrix ( &A );
  Destroy_SuperMatrix_Store ( &B );
  Destroy_SuperNode_Matrix ( &L );
  Destroy_CompCol_Matrix ( &U );
/*
  Say goodbye.
*/
  printf ( "\n" );
  printf ( "SUPER_LU_S2:\n" );
  printf ( "  Normal end of execution.\n");

  return 0;
}
Example #12
0
int main(int argc, char ** argv) {
    uid_t uid = geteuid();

    if ( argv[1] == NULL || argv[2] == NULL ) {
        fprintf(stderr, "USAGE: %s [attach/detach] [image/loop]\n", argv[0]);
        return(1);
    }

    message(VERBOSE, "Checking calling user\n");
    if ( uid != 0 ) {
        message(ERROR, "Calling user must be root\n");
        ABORT(1);
    }

    message(VERBOSE, "Checking command: %s\n", argv[1]);
    if ( strcmp(argv[1], "attach") == 0 ) {
        FILE *containerimage_fp;
        char *containerimage;
        char *loop_dev;

        message(VERBOSE, "Preparing to attach container to loop\n");

        containerimage = xstrdup(argv[2]);

        message(VERBOSE, "Evaluating image: %s\n", containerimage);
    
        message(VERBOSE, "Checking if container image exists\n");
        if ( is_file(containerimage) < 0 ) {
            message(ERROR, "Container image not found: %s\n", containerimage);
            ABORT(1);
        }

        message(VERBOSE, "Checking if container can be opened read/write\n");
        if ( !( containerimage_fp = fopen(containerimage, "r+") ) ) { // Flawfinder: ignore
            message(ERROR, "Could not open image %s: %s\n", containerimage, strerror(errno));
            ABORT(255);
        }

        message(DEBUG, "Binding container to loop interface\n");
        if ( loop_bind(containerimage_fp, &loop_dev, 0) < 0 ) {
            message(ERROR, "Could not bind image to loop!\n");
            ABORT(255);
        }

        printf("%s\n", loop_dev);
    } else if (strcmp(argv[1], "detach") == 0 ) {
        char *loop_dev;

        loop_dev = xstrdup(argv[2]);

        message(VERBOSE, "Preparing to detach loop: %s\n", loop_dev);

        message(VERBOSE, "Checking loop device\n");
        if ( is_blk(loop_dev) < 0 ) {
            message(ERROR, "Block device not found: %s\n", loop_dev);
            ABORT(255);
        }

        message(VERBOSE, "Unbinding container image from loop\n");
        if ( loop_free(loop_dev) < 0 ) {
            message(ERROR, "Failed to detach loop device: %s\n", loop_dev);
            ABORT(255);
        }

    }

    return(0);
}
Example #13
0
// Runs the provided command in a subprocess.
Try<Subprocess> subprocess(
    const string& command,
    const Option<map<string, string> >& environment,
    const Option<lambda::function<int()> >& setup)
{
  // Create pipes for stdin, stdout, stderr.
  // Index 0 is for reading, and index 1 is for writing.
  int stdinPipe[2];
  int stdoutPipe[2];
  int stderrPipe[2];

  if (pipe(stdinPipe) == -1) {
    return ErrnoError("Failed to create pipe");
  } else if (pipe(stdoutPipe) == -1) {
    os::close(stdinPipe[0]);
    os::close(stdinPipe[1]);
    return ErrnoError("Failed to create pipe");
  } else if (pipe(stderrPipe) == -1) {
    os::close(stdinPipe[0]);
    os::close(stdinPipe[1]);
    os::close(stdoutPipe[0]);
    os::close(stdoutPipe[1]);
    return ErrnoError("Failed to create pipe");
  }

  // We need to do this construction before doing the fork as it
  // might not be async-safe.
  // TODO(tillt): Consider optimizing this to not pass an empty map
  // into the constructor or even further to use execl instead of
  // execle once we have no user supplied environment.
  os::ExecEnv envp(environment.get(map<string, string>()));

  pid_t pid;
  if ((pid = fork()) == -1) {
    os::close(stdinPipe[0]);
    os::close(stdinPipe[1]);
    os::close(stdoutPipe[0]);
    os::close(stdoutPipe[1]);
    os::close(stderrPipe[0]);
    os::close(stderrPipe[1]);
    return ErrnoError("Failed to fork");
  }

  Subprocess process;
  process.data->pid = pid;

  if (process.data->pid == 0) {
    // Child.
    // Close parent's end of the pipes.
    os::close(stdinPipe[1]);
    os::close(stdoutPipe[0]);
    os::close(stderrPipe[0]);

    // Make our pipes look like stdin, stderr, stdout before we exec.
    while (dup2(stdinPipe[0], STDIN_FILENO)   == -1 && errno == EINTR);
    while (dup2(stdoutPipe[1], STDOUT_FILENO) == -1 && errno == EINTR);
    while (dup2(stderrPipe[1], STDERR_FILENO) == -1 && errno == EINTR);

    // Close the copies.
    os::close(stdinPipe[0]);
    os::close(stdoutPipe[1]);
    os::close(stderrPipe[1]);

    if (setup.isSome()) {
      int status = setup.get()();
      if (status != 0) {
        _exit(status);
      }
    }

    execle("/bin/sh", "sh", "-c", command.c_str(), (char*) NULL, envp());

    ABORT("Failed to execle '/bin sh -c ", command.c_str(), "'\n");
  }

  // Parent.

  // Close the child's end of the pipes.
  os::close(stdinPipe[0]);
  os::close(stdoutPipe[1]);
  os::close(stderrPipe[1]);

  process.data->in = stdinPipe[1];
  process.data->out = stdoutPipe[0];
  process.data->err = stderrPipe[0];

  // Rather than directly exposing the future from process::reap, we
  // must use an explicit promise so that we can ensure we can receive
  // the termination signal. Otherwise, the caller can discard the
  // reap future, and we will not know when it is safe to close the
  // file descriptors.
  Promise<Option<int> >* promise = new Promise<Option<int> >();
  process.data->status = promise->future();

  // We need to bind a copy of this Subprocess into the onAny callback
  // below to ensure that we don't close the file descriptors before
  // the subprocess has terminated (i.e., because the caller doesn't
  // keep a copy of this Subprocess around themselves).
  process::reap(process.data->pid)
    .onAny(lambda::bind(internal::cleanup, lambda::_1, promise, process));

  return process;
}
void
FUNC ( LALStatus *stat, VTYPE **vector, FILE *stream, BOOLEAN strict )
{ 
  UINT4 i;                 /* an index */
  CHARVector *line = NULL; /* a line of text stored as a CHARVector */
  BufferList head = empty; /* head of linked list of buffers */
  BufferList *here;        /* pointer to current position in list */
  CHAR *start, *end;       /* pointers to start and end of a token */
  TYPE *data;              /* pointer to converted data */
  BOOLEAN more = 1;        /* whether or not to read more numbers */
  UINT4 nTot = 0;          /* total number of numbers read */

  INITSTATUS(stat);
  ATTATCHSTATUSPTR( stat );

  /* Check for valid input arguments. */
  ASSERT( stream, stat, STREAMINPUTH_ENUL, STREAMINPUTH_MSGENUL );
  ASSERT( vector, stat, STREAMINPUTH_ENUL, STREAMINPUTH_MSGENUL );
  ASSERT( !*vector, stat, STREAMINPUTH_EOUT, STREAMINPUTH_MSGEOUT );

  /* Read the line of text as a CHARVector. */
  TRY( LALCHARReadVector( stat->statusPtr, &line, stream ), stat );

  /* Read into first buffer, and see if more needs to be read. */
  start = end = line->data;
  for ( i = 0; more && ( i < BUFFSIZE/SIZE ); i++ ) {
    PARSEFUNC ( stat->statusPtr, head.buf.TYPECODE + i, start, &end );
    BEGINFAIL( stat )
      TRY( LALCHARDestroyVector( stat->statusPtr, &line ), stat );
    ENDFAIL( stat );
    if ( start == end )
      more = 0;
    else {
      nTot++;
      head.size++;
      start = end;
    }
  }

  /* Read into remaining buffers. */
  here = &head;
  while ( more ) {

    /* Allocate next buffer. */
    here->next = (BufferList *)LALMalloc( sizeof(BufferList) );
    here = here->next;
    if ( !here ) {
      FREEBUFFERLIST( head.next );
      TRY( LALCHARDestroyVector( stat->statusPtr, &line ), stat );
      ABORT( stat, STREAMINPUTH_EMEM, STREAMINPUTH_MSGEMEM );
    }
    here->size = 0;
    here->next = NULL;

    /* Read into the next buffer, and see if more needs to be read. */
    for ( i = 0; more && ( i < BUFFSIZE/SIZE ); i++ ) {
      PARSEFUNC ( stat->statusPtr, here->buf.TYPECODE + i, start, &end );
      BEGINFAIL( stat ) {
	FREEBUFFERLIST( head.next );
	TRY( LALCHARDestroyVector( stat->statusPtr, &line ), stat );
      } ENDFAIL( stat );
      if ( start == end )
	more = 0;
      else {
	nTot++;
	here->size++;
	start = end;
      }
    }
  }

  /* Check for formatting problems, if required, and free the line. */
  if ( strict ) {
    if ( nTot == 0 ) {
      FREEBUFFERLIST( head.next );
      TRY( LALCHARDestroyVector( stat->statusPtr, &line ), stat );
      ABORT( stat, STREAMINPUTH_ELEN, STREAMINPUTH_MSGELEN );
    }
    while ( isspace( *end ) )
      end++;
    if ( *end != '\0' ) {
      FREEBUFFERLIST( head.next );
      TRY( LALCHARDestroyVector( stat->statusPtr, &line ), stat );
      ABORT( stat, STREAMINPUTH_EFMT, STREAMINPUTH_MSGEFMT );
    }
  }
  TRY( LALCHARDestroyVector( stat->statusPtr, &line ), stat );

  /* Allocate **vector. */
  if ( nTot > 0 ) {
    CREATEFUNC ( stat->statusPtr, vector, nTot );
    BEGINFAIL( stat )
      FREEBUFFERLIST( head.next );
    ENDFAIL( stat );

    /* Copy buffer list into (*vector)->data, and set
       (*vector)->length. */
    here = &head;
    data = (*vector)->data;
    while ( here ) {
      UINT4 j = here->size;
      TYPE *hereData = here->buf.TYPECODE;
      while ( j-- )
	*(data++) = *(hereData++);
      here = here->next;
    }
  }

  /* Free buffer list and exit. */
  FREEBUFFERLIST( head.next );
  DETATCHSTATUSPTR( stat );
  RETURN( stat );
}
/**
 * \author Creighton, T. D.
 *
 * \brief Computes a continuous waveform with frequency drift and Doppler
 * modulation from an elliptical orbital trajectory.
 *
 * This function computes a quaiperiodic waveform using the spindown and
 * orbital parameters in <tt>*params</tt>, storing the result in
 * <tt>*output</tt>.
 *
 * In the <tt>*params</tt> structure, the routine uses all the "input"
 * fields specified in \ref GenerateSpinOrbitCW_h, and sets all of the
 * "output" fields.  If <tt>params-\>f</tt>=\c NULL, no spindown
 * modulation is performed.  If <tt>params-\>oneMinusEcc</tt>\f$\notin(0,1]\f$
 * (an open orbit), or if
 * <tt>params-\>rPeriNorm</tt>\f$\times\f$<tt>params-\>angularSpeed</tt>\f$\geq1\f$
 * (faster-than-light speed at periapsis), an error is returned.
 *
 * In the <tt>*output</tt> structure, the field <tt>output-\>h</tt> is
 * ignored, but all other pointer fields must be set to \c NULL.  The
 * function will create and allocate space for <tt>output-\>a</tt>,
 * <tt>output-\>f</tt>, and <tt>output-\>phi</tt> as necessary.  The
 * <tt>output-\>shift</tt> field will remain set to \c NULL.
 *
 * ### Algorithm ###
 *
 * For elliptical orbits, we combine \eqref{eq_spinorbit-tr},
 * \eqref{eq_spinorbit-t}, and \eqref{eq_spinorbit-upsilon} to get \f$t_r\f$
 * directly as a function of the eccentric anomaly \f$E\f$:
 * \f{eqnarray}{
 * \label{eq_tr-e1}
 * t_r = t_p & + & \left(\frac{r_p \sin i}{c}\right)\sin\omega\\
 * & + & \left(\frac{P}{2\pi}\right) \left( E +
 * \left[v_p(1-e)\cos\omega - e\right]\sin E
 * + \left[v_p\sqrt{\frac{1-e}{1+e}}\sin\omega\right]
 * [\cos E - 1]\right) \;,
 * \f}
 * where \f$v_p=r_p\dot{\upsilon}_p\sin i/c\f$ is a normalized velocity at
 * periapsis and \f$P=2\pi\sqrt{(1+e)/(1-e)^3}/\dot{\upsilon}_p\f$ is the
 * period of the orbit.  For simplicity we write this as:
 * \f{equation}{
 * \label{eq_tr-e2}
 * t_r = T_p + \frac{1}{n}\left( E + A\sin E + B[\cos E - 1] \right) \;,
 * \f}
 *
 * \figure{inject_eanomaly,eps,0.23,Function to be inverted to find eccentric anomaly}
 *
 * where \f$T_p\f$ is the \e observed time of periapsis passage and
 * \f$n=2\pi/P\f$ is the mean angular speed around the orbit.  Thus the key
 * numerical procedure in this routine is to invert the expression
 * \f$x=E+A\sin E+B(\cos E - 1)\f$ to get \f$E(x)\f$.  We note that
 * \f$E(x+2n\pi)=E(x)+2n\pi\f$, so we only need to solve this expression in
 * the interval \f$[0,2\pi)\f$, sketched to the right.
 *
 * We further note that \f$A^2+B^2<1\f$, although it approaches 1 when
 * \f$e\rightarrow1\f$, or when \f$v_p\rightarrow1\f$ and either \f$e=0\f$ or
 * \f$\omega=\pi\f$.  Except in this limit, Newton-Raphson methods will
 * converge rapidly for any initial guess.  In this limit, though, the
 * slope \f$dx/dE\f$ approaches zero at the point of inflection, and an
 * initial guess or iteration landing near this point will send the next
 * iteration off to unacceptably large or small values.  However, by
 * restricting all initial guesses and iterations to the domain
 * \f$E\in[0,2\pi)\f$, one will always end up on a trajectory branch that
 * will converge uniformly.  This should converge faster than the more
 * generically robust technique of bisection. (Note: the danger with Newton's method
 * has been found to be unstable for certain binary orbital parameters. So if
 * Newton's method fails to converge, a bisection algorithm is employed.)
 *
 * In this algorithm, we start the computation with an arbitrary initial
 * guess of \f$E=0\f$, and refine it until the we get agreement to within
 * 0.01 parts in part in \f$N_\mathrm{cyc}\f$ (where \f$N_\mathrm{cyc}\f$ is the
 * larger of the number of wave cycles in an orbital period, or the
 * number of wave cycles in the entire waveform being generated), or one
 * part in \f$10^{15}\f$ (an order of magnitude off the best precision
 * possible with \c REAL8 numbers).  The latter case indicates that
 * \c REAL8 precision may fail to give accurate phasing, and one
 * should consider modeling the orbit as a set of Taylor frequency
 * coefficients \'{a} la <tt>LALGenerateTaylorCW()</tt>.  On subsequent
 * timesteps, we use the previous timestep as an initial guess, which is
 * good so long as the timesteps are much smaller than an orbital period.
 * This sequence of guesses will have to readjust itself once every orbit
 * (as \f$E\f$ jumps from \f$2\pi\f$ down to 0), but this is relatively
 * infrequent; we don't bother trying to smooth this out because the
 * additional tests would probably slow down the algorithm overall.
 *
 * Once a value of \f$E\f$ is found for a given timestep in the output
 * series, we compute the system time \f$t\f$ via \eqref{eq_spinorbit-t},
 * and use it to determine the wave phase and (non-Doppler-shifted)
 * frequency via \eqref{eq_taylorcw-freq}
 * and \eqref{eq_taylorcw-phi}.  The Doppler shift on the frequency is
 * then computed using \eqref{eq_spinorbit-upsilon}
 * and \eqref{eq_orbit-rdot}.  We use \f$\upsilon\f$ as an intermediate in
 * the Doppler shift calculations, since expressing \f$\dot{R}\f$ directly in
 * terms of \f$E\f$ results in expression of the form \f$(1-e)/(1-e\cos E)\f$,
 * which are difficult to simplify and face precision losses when
 * \f$E\sim0\f$ and \f$e\rightarrow1\f$.  By contrast, solving for \f$\upsilon\f$ is
 * numerically stable provided that the system <tt>atan2()</tt> function is
 * well-designed.
 *
 * The routine does not account for variations in special relativistic or
 * gravitational time dilation due to the elliptical orbit, nor does it
 * deal with other gravitational effects such as Shapiro delay.  To a
 * very rough approximation, the amount of phase error induced by
 * gravitational redshift goes something like \f$\Delta\phi\sim
 * fT(v/c)^2\Delta(r_p/r)\f$, where \f$f\f$ is the typical wave frequency, \f$T\f$
 * is either the length of data or the orbital period (whichever is
 * \e smaller), \f$v\f$ is the \e true (unprojected) speed at
 * periapsis, and \f$\Delta(r_p/r)\f$ is the total range swept out by the
 * quantity \f$r_p/r\f$ over the course of the observation.  Other
 * relativistic effects such as special relativistic time dilation are
 * comparable in magnitude.  We make a crude estimate of when this is
 * significant by noting that \f$v/c\gtrsim v_p\f$ but
 * \f$\Delta(r_p/r)\lesssim 2e/(1+e)\f$; we take these approximations as
 * equalities and require that \f$\Delta\phi\lesssim\pi\f$, giving:
 * \f{equation}{
 * \label{eq_relativistic-orbit}
 * f_0Tv_p^2\frac{4e}{1+e}\lesssim1 \;.
 * \f}
 * When this critereon is violated, a warning is generated.  Furthermore,
 * as noted earlier, when \f$v_p\geq1\f$ the routine will return an error, as
 * faster-than-light speeds can cause the emission and reception times to
 * be non-monotonic functions of one another.
 */
void
LALGenerateEllipticSpinOrbitCW( LALStatus             *stat,
				PulsarCoherentGW            *output,
				SpinOrbitCWParamStruc *params )
{
  UINT4 n, i;              /* number of and index over samples */
  UINT4 nSpin = 0, j;      /* number of and index over spindown terms */
  REAL8 t, dt, tPow;       /* time, interval, and t raised to a power */
  REAL8 phi0, f0, twopif0; /* initial phase, frequency, and 2*pi*f0 */
  REAL8 f, fPrev;          /* current and previous values of frequency */
  REAL4 df = 0.0;          /* maximum difference between f and fPrev */
  REAL8 phi;               /* current value of phase */
  REAL8 p, vDotAvg;        /* orbital period, and 2*pi/(period) */
  REAL8 vp;                /* projected speed at periapsis */
  REAL8 upsilon, argument; /* true anomaly, and argument of periapsis */
  REAL8 eCosOmega;         /* eccentricity * cosine of argument */
  REAL8 tPeriObs;          /* time of observed periapsis */
  REAL8 spinOff;           /* spin epoch - orbit epoch */
  REAL8 x;                 /* observed mean anomaly */
  REAL8 dx, dxMax;         /* current and target errors in x */
  REAL8 a, b;              /* constants in equation for x */
  REAL8 ecc;               /* orbital eccentricity */
  REAL8 oneMinusEcc, onePlusEcc; /* 1 - ecc and 1 + ecc */
  REAL8 e = 0.0;                 /* eccentric anomaly */
  REAL8 de = 0.0;                /* eccentric anomaly step */
  REAL8 sine = 0.0, cose = 0.0;  /* sine of e, and cosine of e minus 1 */
  REAL8 *fSpin = NULL;           /* pointer to Taylor coefficients */
  REAL4 *fData;                  /* pointer to frequency data */
  REAL8 *phiData;                /* pointer to phase data */

  INITSTATUS(stat);
  ATTATCHSTATUSPTR( stat );

  /* Make sure parameter and output structures exist. */
  ASSERT( params, stat, GENERATESPINORBITCWH_ENUL,
	  GENERATESPINORBITCWH_MSGENUL );
  ASSERT( output, stat, GENERATESPINORBITCWH_ENUL,
	  GENERATESPINORBITCWH_MSGENUL );

  /* Make sure output fields don't exist. */
  ASSERT( !( output->a ), stat, GENERATESPINORBITCWH_EOUT,
	  GENERATESPINORBITCWH_MSGEOUT );
  ASSERT( !( output->f ), stat, GENERATESPINORBITCWH_EOUT,
	  GENERATESPINORBITCWH_MSGEOUT );
  ASSERT( !( output->phi ), stat, GENERATESPINORBITCWH_EOUT,
	  GENERATESPINORBITCWH_MSGEOUT );
  ASSERT( !( output->shift ), stat, GENERATESPINORBITCWH_EOUT,
	  GENERATESPINORBITCWH_MSGEOUT );

  /* If Taylor coeficients are specified, make sure they exist. */
  if ( params->f ) {
    ASSERT( params->f->data, stat, GENERATESPINORBITCWH_ENUL,
	    GENERATESPINORBITCWH_MSGENUL );
    nSpin = params->f->length;
    fSpin = params->f->data;
  }

  /* Set up some constants (to avoid repeated calculation or
     dereferencing), and make sure they have acceptable values. */
  oneMinusEcc = params->oneMinusEcc;
  ecc = 1.0 - oneMinusEcc;
  onePlusEcc = 1.0 + ecc;
  if ( ecc < 0.0 || oneMinusEcc <= 0.0 ) {
    ABORT( stat, GENERATESPINORBITCWH_EECC,
	   GENERATESPINORBITCWH_MSGEECC );
  }
  vp = params->rPeriNorm*params->angularSpeed;
  n = params->length;
  dt = params->deltaT;
  f0 = fPrev = params->f0;
  vDotAvg = params->angularSpeed
    *sqrt( oneMinusEcc*oneMinusEcc*oneMinusEcc/onePlusEcc );
  if ( vp >= 1.0 ) {
    ABORT( stat, GENERATESPINORBITCWH_EFTL,
	   GENERATESPINORBITCWH_MSGEFTL );
  }
  if ( vp <= 0.0 || dt <= 0.0 || f0 <= 0.0 || vDotAvg <= 0.0 ||
       n == 0 ) {
    ABORT( stat, GENERATESPINORBITCWH_ESGN,
	   GENERATESPINORBITCWH_MSGESGN );
  }

  /* Set up some other constants. */
  twopif0 = f0*LAL_TWOPI;
  phi0 = params->phi0;
  argument = params->omega;
  p = LAL_TWOPI/vDotAvg;
  a = vp*oneMinusEcc*cos( argument ) + oneMinusEcc - 1.0;
  b = vp*sqrt( oneMinusEcc/( onePlusEcc ) )*sin( argument );
  eCosOmega = ecc*cos( argument );
  if ( n*dt > p )
    dxMax = 0.01/( f0*n*dt );
  else
    dxMax = 0.01/( f0*p );
  if ( dxMax < 1.0e-15 ) {
    dxMax = 1.0e-15;
#ifndef NDEBUG
    LALWarning( stat, "REAL8 arithmetic may not have sufficient"
		" precision for this orbit" );
#endif
  }
#ifndef NDEBUG
  if ( lalDebugLevel & LALWARNING ) {
    REAL8 tau = n*dt;
    if ( tau > p )
      tau = p;
    if ( f0*tau*vp*vp*ecc/onePlusEcc > 0.25 )
      LALWarning( stat, "Orbit may have significant relativistic"
		  " effects that are not included" );
  }
#endif

  /* Compute offset between time series epoch and observed periapsis,
     and betweem true periapsis and spindown reference epoch. */
  tPeriObs = (REAL8)( params->orbitEpoch.gpsSeconds -
		      params->epoch.gpsSeconds );
  tPeriObs += 1.0e-9 * (REAL8)( params->orbitEpoch.gpsNanoSeconds -
				params->epoch.gpsNanoSeconds );
  tPeriObs += params->rPeriNorm*sin( params->omega );
  spinOff = (REAL8)( params->orbitEpoch.gpsSeconds -
		     params->spinEpoch.gpsSeconds );
  spinOff += 1.0e-9 * (REAL8)( params->orbitEpoch.gpsNanoSeconds -
			       params->spinEpoch.gpsNanoSeconds );

  /* Allocate output structures. */
  if ( ( output->a = (REAL4TimeVectorSeries *)
	 LALMalloc( sizeof(REAL4TimeVectorSeries) ) ) == NULL ) {
    ABORT( stat, GENERATESPINORBITCWH_EMEM,
	   GENERATESPINORBITCWH_MSGEMEM );
  }
  memset( output->a, 0, sizeof(REAL4TimeVectorSeries) );
  if ( ( output->f = (REAL4TimeSeries *)
	 LALMalloc( sizeof(REAL4TimeSeries) ) ) == NULL ) {
    LALFree( output->a ); output->a = NULL;
    ABORT( stat, GENERATESPINORBITCWH_EMEM,
	   GENERATESPINORBITCWH_MSGEMEM );
  }
  memset( output->f, 0, sizeof(REAL4TimeSeries) );
  if ( ( output->phi = (REAL8TimeSeries *)
	 LALMalloc( sizeof(REAL8TimeSeries) ) ) == NULL ) {
    LALFree( output->a ); output->a = NULL;
    LALFree( output->f ); output->f = NULL;
    ABORT( stat, GENERATESPINORBITCWH_EMEM,
	   GENERATESPINORBITCWH_MSGEMEM );
  }
  memset( output->phi, 0, sizeof(REAL8TimeSeries) );

  /* Set output structure metadata fields. */
  output->position = params->position;
  output->psi = params->psi;
  output->a->epoch = output->f->epoch = output->phi->epoch
    = params->epoch;
  output->a->deltaT = n*params->deltaT;
  output->f->deltaT = output->phi->deltaT = params->deltaT;
  output->a->sampleUnits = lalStrainUnit;
  output->f->sampleUnits = lalHertzUnit;
  output->phi->sampleUnits = lalDimensionlessUnit;
  snprintf( output->a->name, LALNameLength, "CW amplitudes" );
  snprintf( output->f->name, LALNameLength, "CW frequency" );
  snprintf( output->phi->name, LALNameLength, "CW phase" );

  /* Allocate phase and frequency arrays. */
  LALSCreateVector( stat->statusPtr, &( output->f->data ), n );
  BEGINFAIL( stat ) {
    LALFree( output->a );   output->a = NULL;
    LALFree( output->f );   output->f = NULL;
    LALFree( output->phi ); output->phi = NULL;
  } ENDFAIL( stat );
  LALDCreateVector( stat->statusPtr, &( output->phi->data ), n );
  BEGINFAIL( stat ) {
    TRY( LALSDestroyVector( stat->statusPtr, &( output->f->data ) ),
	 stat );
    LALFree( output->a );   output->a = NULL;
    LALFree( output->f );   output->f = NULL;
    LALFree( output->phi ); output->phi = NULL;
  } ENDFAIL( stat );

  /* Allocate and fill amplitude array. */
  {
    CreateVectorSequenceIn in; /* input to create output->a */
    in.length = 2;
    in.vectorLength = 2;
    LALSCreateVectorSequence( stat->statusPtr, &(output->a->data), &in );
    BEGINFAIL( stat ) {
      TRY( LALSDestroyVector( stat->statusPtr, &( output->f->data ) ),
	   stat );
      TRY( LALDDestroyVector( stat->statusPtr, &( output->phi->data ) ),
	   stat );
      LALFree( output->a );   output->a = NULL;
      LALFree( output->f );   output->f = NULL;
      LALFree( output->phi ); output->phi = NULL;
    } ENDFAIL( stat );
    output->a->data->data[0] = output->a->data->data[2] = params->aPlus;
    output->a->data->data[1] = output->a->data->data[3] = params->aCross;
  }

  /* Fill frequency and phase arrays. */
  fData = output->f->data->data;
  phiData = output->phi->data->data;
  for ( i = 0; i < n; i++ ) {
    INT4 nOrb; /* number of orbits since the specified orbit epoch */

    /* First, find x in the range [0,2*pi]. */
    x = vDotAvg*( i*dt - tPeriObs );
    nOrb = (INT4)( x/LAL_TWOPI );
    if ( x < 0.0 )
      nOrb -= 1;
    x -= LAL_TWOPI*nOrb;

    /* Newton-Raphson iteration to find E(x). Maximum of 100 iterations. */
    INT4 maxiter = 100, iter = 0;
    while ( iter<maxiter && fabs( dx = e + a*sine + b*cose - x ) > dxMax ) {
      iter++;
      //Make a check on the step-size so we don't step too far
      de = dx/( 1.0 + a*cose + a - b*sine );
      if ( de > LAL_PI )
        de = LAL_PI;
      else if ( de < -LAL_PI )
        de = -LAL_PI;
      e -= de;

      if ( e < 0.0 )
        e = 0.0;
      else if ( e > LAL_TWOPI )
        e = LAL_TWOPI;
      sine = sin( e );
      cose = cos( e ) - 1.0;
    }
    /* Bisection algorithm from GSL if Newton's method (above) fails to converge. */
    if (iter==maxiter && fabs( dx = e + a*sine + b*cose - x ) > dxMax ) {
       //Initialize solver
       const gsl_root_fsolver_type *T = gsl_root_fsolver_bisection;
       gsl_root_fsolver *s = gsl_root_fsolver_alloc(T);
       REAL8 e_lo = 0.0, e_hi = LAL_TWOPI;
       gsl_function F;
       struct E_solver_params pars = {a, b, x};
       F.function = &gsl_E_solver;
       F.params = &pars;

       if (gsl_root_fsolver_set(s, &F, e_lo, e_hi) != 0) {
          LALFree( output->a );   output->a = NULL;
          LALFree( output->f );   output->f = NULL;
          LALFree( output->phi ); output->phi = NULL;
          ABORT( stat, -1, "GSL failed to set initial points" );
       }

       INT4 keepgoing = 1;
       INT4 success = 0;
       INT4 root_status = keepgoing;
       e = 0.0;
       iter = 0;
       while (root_status==keepgoing && iter<maxiter) {
          iter++;
          root_status = gsl_root_fsolver_iterate(s);
          if (root_status!=keepgoing && root_status!=success) {
             LALFree( output->a );   output->a = NULL;
             LALFree( output->f );   output->f = NULL;
             LALFree( output->phi ); output->phi = NULL;
             ABORT( stat, -1, "gsl_root_fsolver_iterate() failed" );
          }
          e = gsl_root_fsolver_root(s);
          sine = sin(e);
          cose = cos(e) - 1.0;
          if (fabs( dx = e + a*sine + b*cose - x ) > dxMax) root_status = keepgoing;
          else root_status = success;
       }

       if (root_status!=success) {
          LALFree( output->a );   output->a = NULL;
          LALFree( output->f );   output->f = NULL;
          LALFree( output->phi ); output->phi = NULL;
          gsl_root_fsolver_free(s);
          ABORT( stat, -1, "Could not converge using bisection algorithm" );
       }

       gsl_root_fsolver_free(s);
    }

    /* Compute source emission time, phase, and frequency. */
    phi = t = tPow =
      ( e + LAL_TWOPI*nOrb - ecc*sine )/vDotAvg + spinOff;
    f = 1.0;
    for ( j = 0; j < nSpin; j++ ) {
      f += fSpin[j]*tPow;
      phi += fSpin[j]*( tPow*=t )/( j + 2.0 );
    }

    /* Appy frequency Doppler shift. */
    upsilon = 2.0 * atan2 ( sqrt(onePlusEcc/oneMinusEcc) * sin(0.5*e), cos(0.5*e) );
    f *= f0 / ( 1.0 + vp*( cos( argument + upsilon ) + eCosOmega ) /onePlusEcc );
    phi *= twopif0;
    if ( (i > 0) && (fabs( f - fPrev ) > df) )
      df = fabs( f - fPrev );
    *(fData++) = fPrev = f;
    *(phiData++) = phi + phi0;

  } /* for i < n */

  /* Set output field and return. */
  params->dfdt = df*dt;
  DETATCHSTATUSPTR( stat );
  RETURN( stat );
}