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 ); }
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; }
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; }
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); }
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()); }
/* 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); }
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 */
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; }
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); }
// 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 ); }