static void Decrement(AG_Slider *sl) { AG_Variable *bVal, *bMin, *bMax, *bInc; void *pVal, *pMin, *pMax, *pInc; bVal = AG_GetVariable(sl, "value", &pVal); bMin = AG_GetVariable(sl, "min", &pMin); bMax = AG_GetVariable(sl, "max", &pMax); bInc = AG_GetVariable(sl, "inc", &pInc); switch (AG_VARIABLE_TYPE(bVal)) { case AG_VARIABLE_FLOAT: DECREMENT(float); break; case AG_VARIABLE_DOUBLE: DECREMENT(double); break; #ifdef HAVE_LONG_DOUBLE case AG_VARIABLE_LONG_DOUBLE: DECREMENT(long double); break; #endif case AG_VARIABLE_INT: DECREMENT(int); break; case AG_VARIABLE_UINT: DECREMENT(Uint); break; case AG_VARIABLE_UINT8: DECREMENT(Uint8); break; case AG_VARIABLE_SINT8: DECREMENT(Sint8); break; case AG_VARIABLE_UINT16: DECREMENT(Uint16); break; case AG_VARIABLE_SINT16: DECREMENT(Sint16); break; case AG_VARIABLE_UINT32: DECREMENT(Uint32); break; case AG_VARIABLE_SINT32: DECREMENT(Sint32); break; #ifdef HAVE_64BIT case AG_VARIABLE_UINT64: DECREMENT(Uint64); break; case AG_VARIABLE_SINT64: DECREMENT(Sint64); break; #endif default: break; } AG_PostEvent(NULL, sl, "slider-changed", NULL); AG_UnlockVariable(bVal); AG_UnlockVariable(bMin); AG_UnlockVariable(bMax); AG_UnlockVariable(bInc); AG_Redraw(sl); }
/* * This is the core routine for my read term code. Here is where things like * the up arrow key, editing keys, etc are dealt with. */ char *_rsh_do_read_line(){ char c; rsh_buf_clean(&buf); buf.used = 1; /* For empty command lines. */ current = end; DECREMENT(current); rsh_stack_clean(&hist_stack); CUR_SAVE(); /* Now that we have a buffer... Start filling it. */ while ( read(rsh_fd, &c, 1) != 0 ){ /* Handle escape sequences. 0x1b -> hex escape character. */ if ( c == 0x1b ){ _rsh_handle_escape_seq(); /* Regardless, we do not want to put the escape character into the buf */ continue; } /* Reset the backup buffer so up/down arrow works the way we expect. */ rsh_buf_clean(&backup); /* Deal with EOT from the terminal (Cntr-D). Hack to make RSH work for * project submission. */ if ( c == 0x04 ) rsh_exit(0); /* Backspace */ if ( c == 0x7f ){ _rsh_do_backspace(); goto _display; } /* * Deal with the newline. Otherwise, just add the character to the buffer. */ if ( c == '\n' ) rsh_buf_append(&buf, c); else rsh_buf_insert(&buf, c); /* Now redisplay the buffer. */ _display: rsh_buf_display(&buf); /* If we hit a NL then we should return. */ if ( c == '\n') break; } /* Make sure the buffer is NULL terminated. */ rsh_buf_append(&buf, 0); /* Now set the terminal cursor to where its exepcted to be. */ CUR_NEXT_LINE(); fflush(stdout); return buf.buf; }
/* * Fill buf with a line from the history. 0 = up, non-zero = down. */ void _rsh_do_history_completion(int direction){ int tmp; char *line; if ( start == end ) /* Empty history. */ return; /* * The first thing we must do is backup the current characters in the * buffer. Users don't want their current command to disappear. However, we * should only do this if the backup is not already filled. If the back up * is filled, we can assume that we have already backed up the terminal at * some point. */ if ( ! backup.used ) rsh_buf_copy(&backup, &buf); /* Clean the buf so we can put the history line into buf. */ rsh_buf_clean(&buf); /* This is up, as in we go back into previous commands. */ if ( direction == 0 ){ /* Handle the wrap. */ if ( current == end || ! history[current] ){ current = end; DECREMENT(current); rsh_stack_clean(&hist_stack); } tmp = current; DECREMENT(current); rsh_stack_push(&hist_stack, tmp); /* Copy the text into buf. */ line = history[tmp]; while ( *line ) rsh_buf_insert(&buf, *line++); } else { /* Pop the top frame of the stack, then use the new top frame. */ rsh_stack_pop(&hist_stack); /* This signifies that we should restore the line being edited. */ if ( ! hist_stack.top ){ rsh_buf_copy(&buf, &backup); current = end; goto out_rewrite_line; } /* On the other hand, if we actually have a stack top, copy it into buf */ INCREMENT(current); line = history[hist_stack.top->text]; while ( *line ) rsh_buf_insert(&buf, *line++); } out_rewrite_line: rsh_buf_display(&buf); return; }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Implements 'void Dcm_MainFunction(void)' for DSL. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void DslMain(void) { const Dcm_DslProtocolRowType *protocolRowEntry; const Dcm_DspSessionRowType *sessionRow = NULL; Dcm_DslRunTimeProtocolParametersType *runtime = NULL; protocolRowEntry = DCM_Config.Dsl->DslProtocol->DslProtocolRowList; while (protocolRowEntry->Arc_EOL == FALSE) { runtime = protocolRowEntry->DslRunTimeProtocolParameters; if (runtime != NULL) { // #### HANDLE THE TESTER PRESENT PRESENCE #### if (runtime->sessionControl != DCM_DEFAULT_SESSION) { // Timeout if tester present is lost. if( TRUE == runtime->S3ServerStarted ) { DECREMENT(runtime->S3ServerTimeoutCount); if (runtime->S3ServerTimeoutCount == 0) { changeDiagnosticSession(runtime, DCM_DEFAULT_SESSION); /** @req DCM140 */ runtime->protocolStarted = FALSE; if( (NULL != DcmDslRunTimeData.activeProtocol) && (protocolRowEntry->DslProtocolID == DcmDslRunTimeData.activeProtocol->DslProtocolID) ) { DcmDslRunTimeData.activeProtocol = NULL; } if( (NULL != DcmDslRunTimeData.preemptingProtocol) && (protocolRowEntry->DslProtocolID == DcmDslRunTimeData.preemptingProtocol->DslProtocolID) ) { DcmDslRunTimeData.preemptingProtocol = NULL; } } } } switch (runtime->externalTxBufferStatus) { // #### TX buffer state. #### case NOT_IN_USE: DEBUG( DEBUG_MEDIUM, "state NOT_IN_USE!\n"); break; case PROVIDED_TO_DSD: { DECREMENT(runtime->stateTimeoutCount); if (runtime->stateTimeoutCount == 0) { sessionRow = getActiveSessionRow(runtime); runtime->stateTimeoutCount = DCM_CONVERT_MS_TO_MAIN_CYCLES(sessionRow->DspSessionP2StarServerMax); /* Reinitiate timer, see 9.2.2. */ if (DCM_Config.Dsl->DslDiagResp != NULL) { if (DCM_Config.Dsl->DslDiagResp->DslDiagRespForceRespPendEn == TRUE) { if (runtime->responsePendingCount != 0) { sendResponse(protocolRowEntry, DCM_E_RESPONSEPENDING); /** @req DCM024 */ DECREMENT( runtime->responsePendingCount ); } else { DspCancelPendingRequests(); sendResponse(protocolRowEntry, DCM_E_GENERALREJECT); /** @req DCM120 */ releaseExternalRxTxBuffers(protocolRowEntry, runtime); } } else { DEBUG( DEBUG_MEDIUM, "Not configured to send response pending, now sending general reject!\n"); DspCancelPendingRequests(); sendResponse(protocolRowEntry, DCM_E_GENERALREJECT); releaseExternalRxTxBuffers(protocolRowEntry, runtime); } } } break; } case DSD_PENDING_RESPONSE_SIGNALED: // The DSD has signaled to DSL that the diagnostic response is available in the Tx buffer. // Make sure that response pending or general reject have not been issued, // if so we can not transmit to PduR because we would not know from where // the Tx confirmation resides later. DEBUG( DEBUG_MEDIUM, "state DSD_PENDING_RESPONSE_SIGNALED!\n"); if (runtime->localTxBuffer.status == NOT_IN_USE) { // Make sure that no TxConfirm could be sent by the local buffer and mixed up with this transmission. const Dcm_DslProtocolRxType *protocolRx = NULL; const Dcm_DslMainConnectionType *mainConnection = NULL; const Dcm_DslConnectionType *connection = NULL; const Dcm_DslProtocolRowType *protocolRow = NULL; Std_ReturnType transmitResult; if (findRxPduIdParentConfigurationLeafs(runtime->diagReqestRxPduId, &protocolRx, &mainConnection, &connection, &protocolRow, &runtime)) { const PduIdType txPduId = mainConnection->DslProtocolTx->DcmDslProtocolTxPduId; DEBUG( DEBUG_MEDIUM, "runtime->externalTxBufferStatus enter state DCM_TRANSMIT_SIGNALED.\n" ); runtime->externalTxBufferStatus = DCM_TRANSMIT_SIGNALED; transmitResult = PduR_DcmTransmit(txPduId, &runtime->diagnosticResponseFromDsd); /** @req DCM237 *//* Will trigger PduR (CanTP) to call DslProvideTxBuffer(). */ if (transmitResult != E_OK) { // TODO: What to do here? releaseExternalRxTxBuffers(protocolRow, runtime); } } else { DEBUG( DEBUG_MEDIUM, "***** WARNING, THIS IS UNEXPECTED !!! ********.\n" ); const PduIdType txPduId = protocolRowEntry->DslConnection->DslMainConnection->DslProtocolTx->DcmDslProtocolTxPduId; DEBUG( DEBUG_MEDIUM, "runtime->externalTxBufferStatus enter state DSD_PENDING_RESPONSE_SIGNALED.\n", txPduId); runtime->externalTxBufferStatus = DCM_TRANSMIT_SIGNALED; DEBUG( DEBUG_MEDIUM, "Calling PduR_DcmTransmit with txPduId = %d from DslMain\n", txPduId); transmitResult = PduR_DcmTransmit(txPduId, &runtime->diagnosticResponseFromDsd); /** @req DCM237 *//* Will trigger PduR (CanTP) to call DslProvideTxBuffer(). */ if (transmitResult != E_OK) { // TODO: What to do here? releaseExternalRxTxBuffers(protocolRow, runtime); } } } break; case DCM_TRANSMIT_SIGNALED: DEBUG( DEBUG_MEDIUM, "state DSD_PENDING_RESPONSE_SIGNALED!\n"); break; case PROVIDED_TO_PDUR: // The valid data is being transmitted by TP-layer. DEBUG( DEBUG_MEDIUM, "state DSD_PENDING_RESPONSE_SIGNALED!\n"); break; case PREEMPT_TRANSMIT_NRC: /* preemption has happened,send NRC 0x21 to OBD tester */ // DEBUG( DEBUG_MEDIUM, "state PREEMPT_TRANSMIT_NRC!\n"); if (TRUE == PreemptionNotProcessingDone){ if( !BusyRepeatSent ) { /*sent NRC 0x21 till timeout or processing done*/ sendResponse(protocolRowEntry, DCM_E_BUSYREPEATREQUEST); BusyRepeatSent = TRUE; } /*decrease preempt timeout count*/ DECREMENT(runtime->preemptTimeoutCount); // DEBUG( DEBUG_MEDIUM, "runtime->preemptTimeoutCount = %x\n",runtime->preemptTimeoutCount); /*if processing done is finished,clear the flag*/ // DEBUG( DEBUG_MEDIUM, "DcmDslRunTimeData.activeProtocol->DslRunTimeProtocolParameters->externalTxBufferStatus = %x\n",DcmDslRunTimeData.activeProtocol->DslRunTimeProtocolParameters->externalTxBufferStatus); if (DcmDslRunTimeData.activeProtocol->DslRunTimeProtocolParameters->externalTxBufferStatus == NOT_IN_USE){ /*if processing done is finished,clear the flag*/ PreemptionNotProcessingDone = FALSE; /*close the preempted protocol*/ DcmDslRunTimeData.activeProtocol->DslRunTimeProtocolParameters->protocolStarted = FALSE; /*remove the active protocol and waiting for second OBD request*/ DcmDslRunTimeData.activeProtocol = NULL; /*release current protocol buffer*/ releaseExternalRxTxBuffers(protocolRowEntry, runtime); DcmDslRunTimeData.preemptingProtocol = NULL; } else if(runtime->preemptTimeoutCount == 0){ /*if preempt timeout,clear the flag*/ PreemptionNotProcessingDone = FALSE; /*close the preempted protocol*/ DcmDslRunTimeData.activeProtocol->DslRunTimeProtocolParameters->protocolStarted = FALSE; /*release the extrnal Rx and Tx buffters of the preempted protocol*/ releaseExternalRxTxBuffers(DcmDslRunTimeData.activeProtocol, DcmDslRunTimeData.activeProtocol->DslRunTimeProtocolParameters); /*remove the active protocol and waiting for second OBD request*/ DcmDslRunTimeData.activeProtocol = NULL; /*release the extrnal Rx and Tx buffters of the preempting protocol*/ releaseExternalRxTxBuffers(protocolRowEntry, runtime); DcmDslRunTimeData.preemptingProtocol = NULL; /*initialize DSP*/ DspInit(); } else { } } break; default: break; } } protocolRowEntry++; } }
GLOBAL Int UMF_solve ( Int sys, const Int Ap [ ], const Int Ai [ ], const double Ax [ ], double Xx [ ], const double Bx [ ], #ifdef COMPLEX const double Az [ ], double Xz [ ], const double Bz [ ], #endif NumericType *Numeric, Int irstep, double Info [UMFPACK_INFO], Int Pattern [ ], /* size n */ double SolveWork [ ] /* if irstep>0 real: size 5*n. complex:10*n */ /* otherwise real: size n. complex: 4*n */ ) { /* ---------------------------------------------------------------------- */ /* local variables */ /* ---------------------------------------------------------------------- */ Entry axx, wi, xj, zi, xi, aij, bi ; double omega [3], d, z2i, yi, flops ; Entry *W, *Z, *S, *X ; double *Z2, *Y, *B2, *Rs ; Int *Rperm, *Cperm, i, n, p, step, j, nz, status, p2, do_scale ; #ifdef COMPLEX Int AXsplit ; Int Bsplit ; #endif #ifndef NRECIPROCAL Int do_recip = Numeric->do_recip ; #endif /* ---------------------------------------------------------------------- */ /* initializations */ /* ---------------------------------------------------------------------- */ #ifndef NDEBUG UMF_dump_lu (Numeric) ; ASSERT (Numeric && Xx && Bx && Pattern && SolveWork && Info) ; #endif nz = 0 ; omega [0] = 0. ; omega [1] = 0. ; omega [2] = 0. ; Rperm = Numeric->Rperm ; Cperm = Numeric->Cperm ; Rs = Numeric->Rs ; /* row scale factors */ do_scale = (Rs != (double *) NULL) ; flops = 0 ; Info [UMFPACK_SOLVE_FLOPS] = 0 ; Info [UMFPACK_IR_TAKEN] = 0 ; Info [UMFPACK_IR_ATTEMPTED] = 0 ; /* UMFPACK_solve does not call this routine if A is rectangular */ ASSERT (Numeric->n_row == Numeric->n_col) ; n = Numeric->n_row ; if (Numeric->nnzpiv < n || SCALAR_IS_ZERO (Numeric->rcond) || SCALAR_IS_NAN (Numeric->rcond)) { /* Note that systems involving just L return UMFPACK_OK, even if */ /* A is singular (L is always has a unit diagonal). */ DEBUGm4 (("Note, matrix is singular in umf_solve\n")) ; status = UMFPACK_WARNING_singular_matrix ; irstep = 0 ; } else { status = UMFPACK_OK ; } irstep = MAX (0, irstep) ; /* make sure irstep is >= 0 */ W = (Entry *) SolveWork ; /* Entry W [0..n-1] */ Z = (Entry *) NULL ; /* unused if no iterative refinement */ S = (Entry *) NULL ; Y = (double *) NULL ; Z2 = (double *) NULL ; B2 = (double *) NULL ; #ifdef COMPLEX if (irstep > 0) { if (!Ap || !Ai || !Ax) { return (UMFPACK_ERROR_argument_missing) ; } /* A, B, and X in split format if Az, Bz, and Xz present */ AXsplit = SPLIT (Az) || SPLIT(Xz); Z = (Entry *) (SolveWork + 4*n) ; /* Entry Z [0..n-1] */ S = (Entry *) (SolveWork + 6*n) ; /* Entry S [0..n-1] */ Y = (double *) (SolveWork + 8*n) ; /* double Y [0..n-1] */ B2 = (double *) (SolveWork + 9*n) ; /* double B2 [0..n-1] */ Z2 = (double *) Z ; /* double Z2 [0..n-1], equiv. to Z */ } else { /* A is ignored, only look at X for split/packed cases */ AXsplit = SPLIT(Xz); } Bsplit = SPLIT (Bz); if (AXsplit) { X = (Entry *) (SolveWork + 2*n) ; /* Entry X [0..n-1] */ } else { X = (Entry *) Xx ; /* Entry X [0..n-1] */ } #else X = (Entry *) Xx ; /* Entry X [0..n-1] */ if (irstep > 0) { if (!Ap || !Ai || !Ax) { return (UMFPACK_ERROR_argument_missing) ; } Z = (Entry *) (SolveWork + n) ; /* Entry Z [0..n-1] */ S = (Entry *) (SolveWork + 2*n) ; /* Entry S [0..n-1] */ Y = (double *) (SolveWork + 3*n) ; /* double Y [0..n-1] */ B2 = (double *) (SolveWork + 4*n) ; /* double B2 [0..n-1] */ Z2 = (double *) Z ; /* double Z2 [0..n-1], equiv. to Z */ } #endif /* ---------------------------------------------------------------------- */ /* determine which system to solve */ /* ---------------------------------------------------------------------- */ if (sys == UMFPACK_A) { /* ------------------------------------------------------------------ */ /* solve A x = b with optional iterative refinement */ /* ------------------------------------------------------------------ */ if (irstep > 0) { /* -------------------------------------------------------------- */ /* using iterative refinement: compute Y and B2 */ /* -------------------------------------------------------------- */ nz = Ap [n] ; Info [UMFPACK_NZ] = nz ; /* A is stored by column */ /* Y (i) = ||R A_i||, 1-norm of row i of R A */ for (i = 0 ; i < n ; i++) { Y [i] = 0. ; } flops += (ABS_FLOPS + 1) * nz ; p2 = Ap [n] ; for (p = 0 ; p < p2 ; p++) { /* Y [Ai [p]] += ABS (Ax [p]) ; */ ASSIGN (aij, Ax, Az, p, AXsplit) ; ABS (d, aij) ; Y [Ai [p]] += d ; } /* B2 = abs (B) */ flops += ABS_FLOPS * n ; for (i = 0 ; i < n ; i++) { /* B2 [i] = ABS (B [i]) ; */ ASSIGN (bi, Bx, Bz, i, Bsplit) ; ABS (B2 [i], bi) ; } /* scale Y and B2. */ if (do_scale) { /* Y = R Y */ /* B2 = R B2 */ #ifndef NRECIPROCAL if (do_recip) { /* multiply by the scale factors */ for (i = 0 ; i < n ; i++) { Y [i] *= Rs [i] ; B2 [i] *= Rs [i] ; } } else #endif { /* divide by the scale factors */ for (i = 0 ; i < n ; i++) { Y [i] /= Rs [i] ; B2 [i] /= Rs [i] ; } } flops += 2 * n ; } } for (step = 0 ; step <= irstep ; step++) { /* -------------------------------------------------------------- */ /* Solve A x = b (step 0): */ /* x = Q (U \ (L \ (P R b))) */ /* and then perform iterative refinement (step > 0): */ /* x = x + Q (U \ (L \ (P R (b - A x)))) */ /* -------------------------------------------------------------- */ if (step == 0) { if (do_scale) { /* W = P R b, using X as workspace, since Z is not * allocated if irstep = 0. */ #ifndef NRECIPROCAL if (do_recip) { /* multiply by the scale factors */ for (i = 0 ; i < n ; i++) { ASSIGN (X [i], Bx, Bz, i, Bsplit) ; SCALE (X [i], Rs [i]) ; } } else #endif { /* divide by the scale factors */ for (i = 0 ; i < n ; i++) { ASSIGN (X [i], Bx, Bz, i, Bsplit) ; SCALE_DIV (X [i], Rs [i]) ; } } flops += SCALE_FLOPS * n ; for (i = 0 ; i < n ; i++) { W [i] = X [Rperm [i]] ; } } else { /* W = P b, since the row scaling R = I */ for (i = 0 ; i < n ; i++) { /* W [i] = B [Rperm [i]] ; */ ASSIGN (W [i], Bx, Bz, Rperm [i], Bsplit) ; } } } else { for (i = 0 ; i < n ; i++) { /* Z [i] = B [i] ; */ ASSIGN (Z [i], Bx, Bz, i, Bsplit) ; } flops += MULTSUB_FLOPS * nz ; for (i = 0 ; i < n ; i++) { xi = X [i] ; p2 = Ap [i+1] ; for (p = Ap [i] ; p < p2 ; p++) { /* Z [Ai [p]] -= Ax [p] * xi ; */ ASSIGN (aij, Ax, Az, p, AXsplit) ; MULT_SUB (Z [Ai [p]], aij, xi) ; } } /* scale, Z = R Z */ if (do_scale) { #ifndef NRECIPROCAL if (do_recip) { /* multiply by the scale factors */ for (i = 0 ; i < n ; i++) { SCALE (Z [i], Rs [i]) ; } } else #endif { /* divide by the scale factors */ for (i = 0 ; i < n ; i++) { SCALE_DIV (Z [i], Rs [i]) ; } } flops += SCALE_FLOPS * n ; } for (i = 0 ; i < n ; i++) { W [i] = Z [Rperm [i]] ; } } flops += UMF_lsolve (Numeric, W, Pattern) ; flops += UMF_usolve (Numeric, W, Pattern) ; if (step == 0) { for (i = 0 ; i < n ; i++) { X [Cperm [i]] = W [i] ; } } else { flops += ASSEMBLE_FLOPS * n ; for (i = 0 ; i < n ; i++) { /* X [Cperm [i]] += W [i] ; */ ASSEMBLE (X [Cperm [i]], W [i]) ; } } /* -------------------------------------------------------------- */ /* sparse backward error estimate */ /* -------------------------------------------------------------- */ if (irstep > 0) { /* ---------------------------------------------------------- */ /* A is stored by column */ /* W (i) = R (b - A x)_i, residual */ /* Z2 (i) = R (|A||x|)_i */ /* ---------------------------------------------------------- */ for (i = 0 ; i < n ; i++) { /* W [i] = B [i] ; */ ASSIGN (W [i], Bx, Bz, i, Bsplit) ; Z2 [i] = 0. ; } flops += (MULT_FLOPS + DECREMENT_FLOPS + ABS_FLOPS + 1) * nz ; for (j = 0 ; j < n ; j++) { xj = X [j] ; p2 = Ap [j+1] ; for (p = Ap [j] ; p < p2 ; p++) { i = Ai [p] ; /* axx = Ax [p] * xj ; */ ASSIGN (aij, Ax, Az, p, AXsplit) ; MULT (axx, aij, xj) ; /* W [i] -= axx ; */ DECREMENT (W [i], axx) ; /* Z2 [i] += ABS (axx) ; */ ABS (d, axx) ; Z2 [i] += d ; } } /* scale W and Z2 */ if (do_scale) { /* Z2 = R Z2 */ /* W = R W */ #ifndef NRECIPROCAL if (do_recip) { /* multiply by the scale factors */ for (i = 0 ; i < n ; i++) { SCALE (W [i], Rs [i]) ; Z2 [i] *= Rs [i] ; } } else #endif { /* divide by the scale factors */ for (i = 0 ; i < n ; i++) { SCALE_DIV (W [i], Rs [i]) ; Z2 [i] /= Rs [i] ; } } flops += (SCALE_FLOPS + 1) * n ; } flops += (2*ABS_FLOPS + 5) * n ; if (do_step (omega, step, B2, X, W, Y, Z2, S, n, Info)) { /* iterative refinement is done */ break ; } } } } else if (sys == UMFPACK_At) { /* ------------------------------------------------------------------ */ /* solve A' x = b with optional iterative refinement */ /* ------------------------------------------------------------------ */ /* A' is the complex conjugate transpose */ if (irstep > 0) { /* -------------------------------------------------------------- */ /* using iterative refinement: compute Y */ /* -------------------------------------------------------------- */ nz = Ap [n] ; Info [UMFPACK_NZ] = nz ; /* A' is stored by row */ /* Y (i) = ||(A' R)_i||, 1-norm of row i of A' R */ if (do_scale) { flops += (ABS_FLOPS + 2) * nz ; #ifndef NRECIPROCAL if (do_recip) { /* multiply by the scale factors */ for (i = 0 ; i < n ; i++) { yi = 0. ; p2 = Ap [i+1] ; for (p = Ap [i] ; p < p2 ; p++) { /* yi += ABS (Ax [p]) * Rs [Ai [p]] ; */ /* note that abs (aij) is the same as * abs (conj (aij)) */ ASSIGN (aij, Ax, Az, p, AXsplit) ; ABS (d, aij) ; yi += (d * Rs [Ai [p]]) ; } Y [i] = yi ; } } else #endif { /* divide by the scale factors */ for (i = 0 ; i < n ; i++) { yi = 0. ; p2 = Ap [i+1] ; for (p = Ap [i] ; p < p2 ; p++) { /* yi += ABS (Ax [p]) / Rs [Ai [p]] ; */ /* note that abs (aij) is the same as * abs (conj (aij)) */ ASSIGN (aij, Ax, Az, p, AXsplit) ; ABS (d, aij) ; yi += (d / Rs [Ai [p]]) ; } Y [i] = yi ; } } } else { /* no scaling */ flops += (ABS_FLOPS + 1) * nz ; for (i = 0 ; i < n ; i++) { yi = 0. ; p2 = Ap [i+1] ; for (p = Ap [i] ; p < p2 ; p++) { /* yi += ABS (Ax [p]) ; */ /* note that abs (aij) is the same as * abs (conj (aij)) */ ASSIGN (aij, Ax, Az, p, AXsplit) ; ABS (d, aij) ; yi += d ; } Y [i] = yi ; } } /* B2 = abs (B) */ for (i = 0 ; i < n ; i++) { /* B2 [i] = ABS (B [i]) ; */ ASSIGN (bi, Bx, Bz, i, Bsplit) ; ABS (B2 [i], bi) ; } } for (step = 0 ; step <= irstep ; step++) { /* -------------------------------------------------------------- */ /* Solve A' x = b (step 0): */ /* x = R P' (L' \ (U' \ (Q' b))) */ /* and then perform iterative refinement (step > 0): */ /* x = x + R P' (L' \ (U' \ (Q' (b - A' x)))) */ /* -------------------------------------------------------------- */ if (step == 0) { /* W = Q' b */ for (i = 0 ; i < n ; i++) { /* W [i] = B [Cperm [i]] ; */ ASSIGN (W [i], Bx, Bz, Cperm [i], Bsplit) ; } } else { /* Z = b - A' x */ for (i = 0 ; i < n ; i++) { /* Z [i] = B [i] ; */ ASSIGN (Z [i], Bx, Bz, i, Bsplit) ; } flops += MULTSUB_FLOPS * nz ; for (i = 0 ; i < n ; i++) { zi = Z [i] ; p2 = Ap [i+1] ; for (p = Ap [i] ; p < p2 ; p++) { /* zi -= conjugate (Ax [p]) * X [Ai [p]] ; */ ASSIGN (aij, Ax, Az, p, Bsplit) ; MULT_SUB_CONJ (zi, X [Ai [p]], aij) ; } Z [i] = zi ; } /* W = Q' Z */ for (i = 0 ; i < n ; i++) { W [i] = Z [Cperm [i]] ; } } flops += UMF_uhsolve (Numeric, W, Pattern) ; flops += UMF_lhsolve (Numeric, W, Pattern) ; if (step == 0) { /* X = R P' W */ /* do not use Z, since it isn't allocated if irstep = 0 */ /* X = P' W */ for (i = 0 ; i < n ; i++) { X [Rperm [i]] = W [i] ; } if (do_scale) { /* X = R X */ #ifndef NRECIPROCAL if (do_recip) { /* multiply by the scale factors */ for (i = 0 ; i < n ; i++) { SCALE (X [i], Rs [i]) ; } } else #endif { /* divide by the scale factors */ for (i = 0 ; i < n ; i++) { SCALE_DIV (X [i], Rs [i]) ; } } flops += SCALE_FLOPS * n ; } } else { /* Z = P' W */ for (i = 0 ; i < n ; i++) { Z [Rperm [i]] = W [i] ; } if (do_scale) { /* Z = R Z */ #ifndef NRECIPROCAL if (do_recip) { /* multiply by the scale factors */ for (i = 0 ; i < n ; i++) { SCALE (Z [i], Rs [i]) ; } } else #endif { /* divide by the scale factors */ for (i = 0 ; i < n ; i++) { SCALE_DIV (Z [i], Rs [i]) ; } } flops += SCALE_FLOPS * n ; } flops += ASSEMBLE_FLOPS * n ; /* X += Z */ for (i = 0 ; i < n ; i++) { /* X [i] += Z [i] ; was +=W[i] in v4.3, which is wrong */ ASSEMBLE (X [i], Z [i]) ; /* bug fix, v4.3.1 */ } } /* -------------------------------------------------------------- */ /* sparse backward error estimate */ /* -------------------------------------------------------------- */ if (irstep > 0) { /* ---------------------------------------------------------- */ /* A' is stored by row */ /* W (i) = (b - A' x)_i, residual */ /* Z2 (i) = (|A'||x|)_i */ /* ---------------------------------------------------------- */ flops += (MULT_FLOPS + DECREMENT_FLOPS + ABS_FLOPS + 1) * nz ; for (i = 0 ; i < n ; i++) { /* wi = B [i] ; */ ASSIGN (wi, Bx, Bz, i, Bsplit) ; z2i = 0. ; p2 = Ap [i+1] ; for (p = Ap [i] ; p < p2 ; p++) { /* axx = conjugate (Ax [p]) * X [Ai [p]] ; */ ASSIGN (aij, Ax, Az, p, AXsplit) ; MULT_CONJ (axx, X [Ai [p]], aij) ; /* wi -= axx ; */ DECREMENT (wi, axx) ; /* z2i += ABS (axx) ; */ ABS (d, axx) ; z2i += d ; } W [i] = wi ; Z2 [i] = z2i ; } flops += (2*ABS_FLOPS + 5) * n ; if (do_step (omega, step, B2, X, W, Y, Z2, S, n, Info)) { /* iterative refinement is done */ break ; } } } } else if (sys == UMFPACK_Aat) { /* ------------------------------------------------------------------ */ /* solve A.' x = b with optional iterative refinement */ /* ------------------------------------------------------------------ */ /* A' is the array transpose */ if (irstep > 0) { /* -------------------------------------------------------------- */ /* using iterative refinement: compute Y */ /* -------------------------------------------------------------- */ nz = Ap [n] ; Info [UMFPACK_NZ] = nz ; /* A.' is stored by row */ /* Y (i) = ||(A.' R)_i||, 1-norm of row i of A.' R */ if (do_scale) { flops += (ABS_FLOPS + 2) * nz ; #ifndef NRECIPROCAL if (do_recip) { /* multiply by the scale factors */ for (i = 0 ; i < n ; i++) { yi = 0. ; p2 = Ap [i+1] ; for (p = Ap [i] ; p < p2 ; p++) { /* yi += ABS (Ax [p]) * Rs [Ai [p]] ; */ /* note that A.' is the array transpose, * so no conjugate */ ASSIGN (aij, Ax, Az, p, AXsplit) ; ABS (d, aij) ; yi += (d * Rs [Ai [p]]) ; } Y [i] = yi ; } } else #endif { /* divide by the scale factors */ for (i = 0 ; i < n ; i++) { yi = 0. ; p2 = Ap [i+1] ; for (p = Ap [i] ; p < p2 ; p++) { /* yi += ABS (Ax [p]) / Rs [Ai [p]] ; */ /* note that A.' is the array transpose, * so no conjugate */ ASSIGN (aij, Ax, Az, p, AXsplit) ; ABS (d, aij) ; yi += (d / Rs [Ai [p]]) ; } Y [i] = yi ; } } } else { /* no scaling */ flops += (ABS_FLOPS + 1) * nz ; for (i = 0 ; i < n ; i++) { yi = 0. ; p2 = Ap [i+1] ; for (p = Ap [i] ; p < p2 ; p++) { /* yi += ABS (Ax [p]) */ /* note that A.' is the array transpose, * so no conjugate */ ASSIGN (aij, Ax, Az, p, AXsplit) ; ABS (d, aij) ; yi += d ; } Y [i] = yi ; } } /* B2 = abs (B) */ for (i = 0 ; i < n ; i++) { /* B2 [i] = ABS (B [i]) ; */ ASSIGN (bi, Bx, Bz, i, Bsplit) ; ABS (B2 [i], bi) ; } } for (step = 0 ; step <= irstep ; step++) { /* -------------------------------------------------------------- */ /* Solve A.' x = b (step 0): */ /* x = R P' (L.' \ (U.' \ (Q' b))) */ /* and then perform iterative refinement (step > 0): */ /* x = x + R P' (L.' \ (U.' \ (Q' (b - A.' x)))) */ /* -------------------------------------------------------------- */ if (step == 0) { /* W = Q' b */ for (i = 0 ; i < n ; i++) { /* W [i] = B [Cperm [i]] ; */ ASSIGN (W [i], Bx, Bz, Cperm [i], Bsplit) ; } } else { /* Z = b - A.' x */ for (i = 0 ; i < n ; i++) { /* Z [i] = B [i] ; */ ASSIGN (Z [i], Bx, Bz, i, Bsplit) ; } flops += MULTSUB_FLOPS * nz ; for (i = 0 ; i < n ; i++) { zi = Z [i] ; p2 = Ap [i+1] ; for (p = Ap [i] ; p < p2 ; p++) { /* zi -= Ax [p] * X [Ai [p]] ; */ ASSIGN (aij, Ax, Az, p, AXsplit) ; MULT_SUB (zi, aij, X [Ai [p]]) ; } Z [i] = zi ; } /* W = Q' Z */ for (i = 0 ; i < n ; i++) { W [i] = Z [Cperm [i]] ; } } flops += UMF_utsolve (Numeric, W, Pattern) ; flops += UMF_ltsolve (Numeric, W, Pattern) ; if (step == 0) { /* X = R P' W */ /* do not use Z, since it isn't allocated if irstep = 0 */ /* X = P' W */ for (i = 0 ; i < n ; i++) { X [Rperm [i]] = W [i] ; } if (do_scale) { /* X = R X */ #ifndef NRECIPROCAL if (do_recip) { /* multiply by the scale factors */ for (i = 0 ; i < n ; i++) { SCALE (X [i], Rs [i]) ; } } else #endif { /* divide by the scale factors */ for (i = 0 ; i < n ; i++) { SCALE_DIV (X [i], Rs [i]) ; } } flops += SCALE_FLOPS * n ; } } else { /* Z = P' W */ for (i = 0 ; i < n ; i++) { Z [Rperm [i]] = W [i] ; } if (do_scale) { /* Z = R Z */ #ifndef NRECIPROCAL if (do_recip) { /* multiply by the scale factors */ for (i = 0 ; i < n ; i++) { SCALE (Z [i], Rs [i]) ; } } else #endif { /* divide by the scale factors */ for (i = 0 ; i < n ; i++) { SCALE_DIV (Z [i], Rs [i]) ; } } flops += SCALE_FLOPS * n ; } flops += ASSEMBLE_FLOPS * n ; /* X += Z */ for (i = 0 ; i < n ; i++) { /* X [i] += Z [i] ; was +=W[i] in v4.3, which is wrong */ ASSEMBLE (X [i], Z [i]) ; /* bug fix, v4.3.1 */ } } /* -------------------------------------------------------------- */ /* sparse backward error estimate */ /* -------------------------------------------------------------- */ if (irstep > 0) { /* ---------------------------------------------------------- */ /* A.' is stored by row */ /* W (i) = (b - A.' x)_i, residual */ /* Z (i) = (|A.'||x|)_i */ /* ---------------------------------------------------------- */ flops += (MULT_FLOPS + DECREMENT_FLOPS + ABS_FLOPS + 1) * nz ; for (i = 0 ; i < n ; i++) { /* wi = B [i] ; */ ASSIGN (wi, Bx, Bz, i, Bsplit) ; z2i = 0. ; p2 = Ap [i+1] ; for (p = Ap [i] ; p < p2 ; p++) { /* axx = Ax [p] * X [Ai [p]] ; */ ASSIGN (aij, Ax, Az, p, AXsplit) ; MULT (axx, aij, X [Ai [p]]) ; /* wi -= axx ; */ DECREMENT (wi, axx) ; /* z2i += ABS (axx) ; */ ABS (d, axx) ; z2i += d ; } W [i] = wi ; Z2 [i] = z2i ; } flops += (2*ABS_FLOPS + 5) * n ; if (do_step (omega, step, B2, X, W, Y, Z2, S, n, Info)) { /* iterative refinement is done */ break ; } } } } else if (sys == UMFPACK_Pt_L) { /* ------------------------------------------------------------------ */ /* Solve P'Lx=b: x = L \ Pb */ /* ------------------------------------------------------------------ */ for (i = 0 ; i < n ; i++) { /* X [i] = B [Rperm [i]] ; */ ASSIGN (X [i], Bx, Bz, Rperm [i], Bsplit) ; } flops = UMF_lsolve (Numeric, X, Pattern) ; status = UMFPACK_OK ; } else if (sys == UMFPACK_L) { /* ------------------------------------------------------------------ */ /* Solve Lx=b: x = L \ b */ /* ------------------------------------------------------------------ */ for (i = 0 ; i < n ; i++) { /* X [i] = B [i] ; */ ASSIGN (X [i], Bx, Bz, i, Bsplit) ; } flops = UMF_lsolve (Numeric, X, Pattern) ; status = UMFPACK_OK ; } else if (sys == UMFPACK_Lt_P) { /* ------------------------------------------------------------------ */ /* Solve L'Px=b: x = P' (L' \ b) */ /* ------------------------------------------------------------------ */ for (i = 0 ; i < n ; i++) { /* W [i] = B [i] ; */ ASSIGN (W [i], Bx, Bz, i, Bsplit) ; } flops = UMF_lhsolve (Numeric, W, Pattern) ; for (i = 0 ; i < n ; i++) { X [Rperm [i]] = W [i] ; } status = UMFPACK_OK ; } else if (sys == UMFPACK_Lat_P) { /* ------------------------------------------------------------------ */ /* Solve L.'Px=b: x = P' (L.' \ b) */ /* ------------------------------------------------------------------ */ for (i = 0 ; i < n ; i++) { /* W [i] = B [i] ; */ ASSIGN (W [i], Bx, Bz, i, Bsplit) ; } flops = UMF_ltsolve (Numeric, W, Pattern) ; for (i = 0 ; i < n ; i++) { X [Rperm [i]] = W [i] ; } status = UMFPACK_OK ; } else if (sys == UMFPACK_Lt) { /* ------------------------------------------------------------------ */ /* Solve L'x=b: x = L' \ b */ /* ------------------------------------------------------------------ */ for (i = 0 ; i < n ; i++) { /* X [i] = B [i] ; */ ASSIGN (X [i], Bx, Bz, i, Bsplit) ; } flops = UMF_lhsolve (Numeric, X, Pattern) ; status = UMFPACK_OK ; } else if (sys == UMFPACK_Lat) { /* ------------------------------------------------------------------ */ /* Solve L.'x=b: x = L.' \ b */ /* ------------------------------------------------------------------ */ for (i = 0 ; i < n ; i++) { /* X [i] = B [i] ; */ ASSIGN (X [i], Bx, Bz, i, Bsplit) ; } flops = UMF_ltsolve (Numeric, X, Pattern) ; status = UMFPACK_OK ; } else if (sys == UMFPACK_U_Qt) { /* ------------------------------------------------------------------ */ /* Solve UQ'x=b: x = Q (U \ b) */ /* ------------------------------------------------------------------ */ for (i = 0 ; i < n ; i++) { /* W [i] = B [i] ; */ ASSIGN (W [i], Bx, Bz, i, Bsplit) ; } flops = UMF_usolve (Numeric, W, Pattern) ; for (i = 0 ; i < n ; i++) { X [Cperm [i]] = W [i] ; } } else if (sys == UMFPACK_U) { /* ------------------------------------------------------------------ */ /* Solve Ux=b: x = U \ b */ /* ------------------------------------------------------------------ */ for (i = 0 ; i < n ; i++) { /* X [i] = B [i] ; */ ASSIGN (X [i], Bx, Bz, i, Bsplit) ; } flops = UMF_usolve (Numeric, X, Pattern) ; } else if (sys == UMFPACK_Q_Ut) { /* ------------------------------------------------------------------ */ /* Solve QU'x=b: x = U' \ Q'b */ /* ------------------------------------------------------------------ */ for (i = 0 ; i < n ; i++) { /* X [i] = B [Cperm [i]] ; */ ASSIGN (X [i], Bx, Bz, Cperm [i], Bsplit) ; } flops = UMF_uhsolve (Numeric, X, Pattern) ; } else if (sys == UMFPACK_Q_Uat) { /* ------------------------------------------------------------------ */ /* Solve QU.'x=b: x = U.' \ Q'b */ /* ------------------------------------------------------------------ */ for (i = 0 ; i < n ; i++) { /* X [i] = B [Cperm [i]] ; */ ASSIGN (X [i], Bx, Bz, Cperm [i], Bsplit) ; } flops = UMF_utsolve (Numeric, X, Pattern) ; } else if (sys == UMFPACK_Ut) { /* ------------------------------------------------------------------ */ /* Solve U'x=b: x = U' \ b */ /* ------------------------------------------------------------------ */ for (i = 0 ; i < n ; i++) { /* X [i] = B [i] ; */ ASSIGN (X [i], Bx, Bz, i, Bsplit) ; } flops = UMF_uhsolve (Numeric, X, Pattern) ; } else if (sys == UMFPACK_Uat) { /* ------------------------------------------------------------------ */ /* Solve U'x=b: x = U' \ b */ /* ------------------------------------------------------------------ */ for (i = 0 ; i < n ; i++) { /* X [i] = B [i] ; */ ASSIGN (X [i], Bx, Bz, i, Bsplit) ; } flops = UMF_utsolve (Numeric, X, Pattern) ; } else { return (UMFPACK_ERROR_invalid_system) ; } #ifdef COMPLEX /* copy the solution back, from Entry X [ ] to double Xx [ ] and Xz [ ] */ if (AXsplit) { for (i = 0 ; i < n ; i++) { Xx [i] = REAL_COMPONENT (X [i]) ; Xz [i] = IMAG_COMPONENT (X [i]) ; } } #endif /* return UMFPACK_OK, or UMFPACK_WARNING_singular_matrix */ /* Note that systems involving just L will return UMFPACK_OK */ Info [UMFPACK_SOLVE_FLOPS] = flops ; return (status) ; }