PRIVATE void dump_singletons ( Int head, /* head of the queue */ Int tail, /* tail of the queue */ Int Next [ ], /* Next [i] is the next object after i */ char *name, /* "row" or "col" */ Int Deg [ ], /* Deg [i] is the degree of object i */ Int n /* objects are in the range 0 to n-1 */ ) { Int i, next, cnt ; DEBUG6 (("%s Singleton list: head "ID" tail "ID"\n", name, head, tail)) ; i = head ; ASSERT (head >= EMPTY && head < n) ; ASSERT (tail >= EMPTY && tail < n) ; cnt = 0 ; while (i != EMPTY) { DEBUG7 ((" "ID": "ID" deg: "ID"\n", cnt, i, Deg [i])) ; ASSERT (i >= 0 && i < n) ; next = Next [i] ; if (i == tail) ASSERT (next == EMPTY) ; i = next ; cnt++ ; ASSERT (cnt <= n) ; } }
// --------------------------------------------------------------------------- // --------------------------------------------------------------------------- // void core_scan_list_c::print_contents() { u32_t size( sizeof( *this ) ); u64_t timestamp = core_am_tools_c::timestamp(); for( core_scan_list_entry_s* iter = scan_list_m.first(); iter; iter = scan_list_m.next() ) { const core_mac_address_s bssid( iter->ap_data->bssid() ); core_ssid_s ssid( iter->ap_data->ssid() ); DEBUG6( "core_scan_list_c::print_contents() - BSSID %02X:%02X:%02X:%02X:%02X:%02X", bssid.addr[0], bssid.addr[1], bssid.addr[2], bssid.addr[3], bssid.addr[4], bssid.addr[5] ); DEBUG1S( "core_scan_list_c::print_contents() - SSID ", ssid.length, &ssid.ssid[0] ); DEBUG1( "core_scan_list_c::print_contents() - age %u second(s)", static_cast<u32_t>( timestamp - iter->timestamp ) / SECONDS_FROM_MICROSECONDS ); DEBUG1( "core_scan_list_c::print_contents() - tags 0x%02X", iter->tags ); DEBUG( "core_scan_list_c::print_contents()" ); size += sizeof( *iter ) + sizeof( *iter->ap_data ) + sizeof( *iter->ap_data->frame() ) + iter->ap_data->frame()->data_length(); } DEBUG2( "core_scan_list_c::print_contents() - total size for scan list is %u bytes with %u AP(s)", size, count() ); }
// --------------------------------------------------------------------------- // From class MWlanBgScanProvider. // CWlanBgScan::NotifyChangedSettings // --------------------------------------------------------------------------- // void CWlanBgScan::NotifyChangedSettings( MWlanBgScanProvider::TWlanBgScanSettings& aSettings ) { DEBUG6( "CWlanBgScan::NotifyChangedSettings( interval: %u, psm srv mode: %u, peak start: %04u, peak end: %04u, peak: %u, off-peak: %u )", aSettings.backgroundScanInterval, aSettings.psmServerMode, aSettings.bgScanPeakStartTime, aSettings.bgScanPeakEndTime, aSettings.bgScanIntervalPeak, aSettings.bgScanIntervalOffPeak); // validate settings and use default values if needed MWlanBgScanProvider::TWlanBgScanSettings settingsToUse; CheckSettings( settingsToUse, aSettings ); // Note: Any PSM server mode value is allowed. // store settings for later use iBgScanSettings = settingsToUse; IntervalChanged(); if( iCurrentPsmServerMode != iBgScanSettings.psmServerMode ) { if( AwsPresence() == CWlanBgScan::EAwsPresent ) { DEBUG( "CWlanBgScan::NotifyChangedSettings() - sending power mode command to AWS" ); MWlanBgScanAwsComms::TAwsMessage msg = { MWlanBgScanAwsComms::ESetPowerSaveMode, iBgScanSettings.psmServerMode }; iAwsComms->SendOrQueueAwsCommand( msg ); } // remember current psm server mode iCurrentPsmServerMode = iBgScanSettings.psmServerMode; } }
PRIVATE void dump_mat ( char *xname, char *yname, Int nx, Int ny, const Int Xp [ ], const Int Xi [ ], Int Xdeg [ ], Int Ydeg [ ] ) { Int x, y, p, p1, p2, xdeg, do_xdeg, ydeg ; DEBUG6 (("\n ==== Dump %s mat:\n", xname)) ; for (x = 0 ; x < nx ; x++) { p1 = Xp [x] ; p2 = Xp [x+1] ; xdeg = Xdeg [x] ; DEBUG6 (("Dump %s "ID" p1 "ID" p2 "ID" deg "ID"\n", xname, x, p1, p2, xdeg)) ; do_xdeg = (xdeg >= 0) ; for (p = p1 ; p < p2 ; p++) { y = Xi [p] ; DEBUG7 ((" %s "ID" deg: ", yname, y)) ; ASSERT (y >= 0 && y < ny) ; ydeg = Ydeg [y] ; DEBUG7 ((ID"\n", ydeg)) ; if (do_xdeg && ydeg >= 0) { xdeg-- ; } } ASSERT (IMPLIES (do_xdeg, xdeg == 0)) ; } }
// --------------------------------------------------------------------------- // --------------------------------------------------------------------------- // void core_scan_list_c::remove_entries_by_bssid( const core_mac_address_s& bssid ) { DEBUG6( "core_scan_list_c::remove_entries_by_bssid() - removing entries with BSSID %02X:%02X:%02X:%02X:%02X:%02X", bssid.addr[0], bssid.addr[1], bssid.addr[2], bssid.addr[3], bssid.addr[4], bssid.addr[5] ); core_type_list_iterator_c<core_scan_list_entry_s> iter( scan_list_m ); for( core_scan_list_entry_s* current = iter.first(); current; current = iter.next() ) { if ( current->ap_data->bssid() == bssid ) { DEBUG( "core_scan_list_c::remove_entries_by_bssid() - matching entry found" ); iter.remove(); delete current->ap_data; delete current; current = NULL; } } }
// --------------------------------------------------------- // CWlanMgmtCommandHandler::AddCipherKey // --------------------------------------------------------- // void CWlanMgmtCommandHandler::AddCipherKey( TWlanCipherSuite aCipherSuite, TUint8 aKeyIndex, TUint32 aLength, const TUint8* aData, const TMacAddress& aMacAddr, TBool aUseAsDefault ) { DEBUG( "CWlanMgmtCommandHandler::AddCipherKey()" ); DEBUG1( "CWlanMgmtCommandHandler::AddCipherKey() - aCipherSuite = %u", aCipherSuite ); DEBUG1( "CWlanMgmtCommandHandler::AddCipherKey() - aKeyIndex = %u", aKeyIndex ); DEBUG1( "CWlanMgmtCommandHandler::AddCipherKey() - aUseAsDefault = %u", aUseAsDefault ); DEBUG6( "CWlanMgmtCommandHandler::AddCipherKey() - aMacAddr = %02X:%02X:%02X:%02X:%02X:%02X", aMacAddr.iMacAddress[0], aMacAddr.iMacAddress[1], aMacAddr.iMacAddress[2], aMacAddr.iMacAddress[3], aMacAddr.iMacAddress[4], aMacAddr.iMacAddress[5] ); DEBUG1( "CWlanMgmtCommandHandler::AddCipherKey() - aLength = %u", aLength ); DEBUG_BUFFER( aLength, aData ); TAddCipherKeyMsg msg; msg.hdr.oid_id = E802_11_ADD_CIPHER_KEY; msg.cipherSuite = aCipherSuite; Mem::Copy( msg.data, aData, aLength ); msg.length = aLength; msg.keyIndex = aKeyIndex; msg.macAddress = aMacAddr; msg.useAsDefaultKey = aUseAsDefault; TPckg<TAddCipherKeyMsg> buf( msg ); TInt err = iChannel.ManagementCommand( buf, NULL ); if( err ) { DEBUG1("ERROR calling RWlanLogicalChannel::ManagementCommand(): %d", err ); } }
GLOBAL void UMF_assemble #else GLOBAL void UMF_assemble_fixq #endif ( NumericType *Numeric, WorkType *Work ) { /* ---------------------------------------------------------------------- */ /* local variables */ /* ---------------------------------------------------------------------- */ Int e, i, row, col, i2, nrows, ncols, f, tpi, extcdeg, extrdeg, rdeg0, cdeg0, son_list, next, nrows_to_assemble, ncols_to_assemble, ngetrows, j, j2, nrowsleft, /* number of rows remaining in S */ ncolsleft, /* number of columns remaining in S */ prior_Lson, prior_Uson, *E, *Cols, *Rows, *Wm, *Woo, *Row_tuples, *Row_degree, *Row_tlen, *Col_tuples, *Col_tlen ; Unit *Memory, *p ; Element *ep ; Tuple *tp, *tp1, *tp2, *tpend ; Entry *S, /* a pointer into the contribution block of a son */ *Fcblock, /* current contribution block */ *Fcol ; /* a column of FC */ Int *Frpos, *Fcpos, fnrows, /* number of rows in contribution block in F */ fncols ; /* number of columns in contribution block in F */ #if !defined (FIXQ) || !defined (NDEBUG) Int *Col_degree ; #endif #ifndef NDEBUG Int n_row, n_col ; n_row = Work->n_row ; n_col = Work->n_col ; DEBUG3 (("::Assemble SCANS 1-4\n")) ; UMF_dump_current_front (Numeric, Work, TRUE) ; #endif #if !defined (FIXQ) || !defined (NDEBUG) Col_degree = Numeric->Cperm ; /* not updated if FIXQ is true */ #endif /* ---------------------------------------------------------------------- */ /* get parameters */ /* ---------------------------------------------------------------------- */ fncols = Work->fncols ; fnrows = Work->fnrows ; Fcpos = Work->Fcpos ; Frpos = Work->Frpos ; Row_degree = Numeric->Rperm ; Row_tuples = Numeric->Uip ; Row_tlen = Numeric->Uilen ; Col_tuples = Numeric->Lip ; Col_tlen = Numeric->Lilen ; E = Work->E ; Memory = Numeric->Memory ; Wm = Work->Wm ; Woo = Work->Woo ; rdeg0 = Work->rdeg0 ; cdeg0 = Work->cdeg0 ; #ifndef NDEBUG DEBUG6 (("============================================\n")) ; DEBUG6 (("Degree update, assembly.\n")) ; DEBUG6 (("pivot row pattern: fncols="ID"\n", fncols)) ; for (j = 0 ; j < fncols ; j++) { col = Work->Fcols [j] ; DEBUG6 ((ID" ", col)) ; ASSERT (Fcpos [col] == j * Work->fnr_curr) ; ASSERT (NON_PIVOTAL_COL (col)) ; } ASSERT (Fcpos [Work->pivcol] >= 0) ; DEBUG6 (("pivcol: "ID" pos "ID" fnr_curr "ID" fncols "ID"\n", Work->pivcol, Fcpos [Work->pivcol], Work->fnr_curr, fncols)) ; ASSERT (Fcpos [Work->pivcol] < fncols * Work->fnr_curr) ; DEBUG6 (("\npivot col pattern: fnrows="ID"\n", fnrows)) ; for (i = 0 ; i < fnrows ; i++) { row = Work->Frows [i] ; DEBUG6 ((ID" ", row)) ; ASSERT (Frpos [row] == i) ; ASSERT (NON_PIVOTAL_ROW (row)) ; } DEBUG6 (("\n")) ; ASSERT (Frpos [Work->pivrow] >= 0) ; ASSERT (Frpos [Work->pivrow] < fnrows) ; ASSERT (Work->Flublock == (Entry *) (Numeric->Memory + E [0])) ; ASSERT (Work->Fcblock == Work->Flublock + Work->nb * (Work->nb + Work->fnr_curr + Work->fnc_curr)) ; #endif Fcblock = Work->Fcblock ; /* ---------------------------------------------------------------------- */ /* determine the largest actual frontal matrix size (for Info only) */ /* ---------------------------------------------------------------------- */ ASSERT (fnrows == Work->fnrows_new + 1) ; ASSERT (fncols == Work->fncols_new + 1) ; Numeric->maxnrows = MAX (Numeric->maxnrows, fnrows) ; Numeric->maxncols = MAX (Numeric->maxncols, fncols) ; /* this is safe from integer overflow, since the current frontal matrix * is already allocated. */ Numeric->maxfrsize = MAX (Numeric->maxfrsize, fnrows * fncols) ; /* ---------------------------------------------------------------------- */ /* assemble from prior elements into the current frontal matrix */ /* ---------------------------------------------------------------------- */ DEBUG2 (("New assemble start [prior_element:"ID"\n", Work->prior_element)) ; /* Currently no rows or columns are marked. No elements are scanned, */ /* that is, (ep->next == EMPTY) is true for all elements */ son_list = 0 ; /* start creating son_list [ */ /* ---------------------------------------------------------------------- */ /* determine if most recent element is Lson or Uson of current front */ /* ---------------------------------------------------------------------- */ if (!Work->do_extend) { prior_Uson = ( Work->pivcol_in_front && !Work->pivrow_in_front) ; prior_Lson = (!Work->pivcol_in_front && Work->pivrow_in_front) ; if (prior_Uson || prior_Lson) { e = Work->prior_element ; if (e != EMPTY) { ASSERT (E [e]) ; p = Memory + E [e] ; ep = (Element *) p ; ep->next = son_list ; son_list = e ; #ifndef NDEBUG DEBUG2 (("e "ID" is Prior son "ID" "ID"\n", e, prior_Uson, prior_Lson)) ; UMF_dump_element (Numeric, Work, e, FALSE) ; #endif ASSERT (E [e]) ; } } } Work->prior_element = EMPTY ; /* ---------------------------------------------------------------------- */ /* SCAN1-row: scan the element lists of each new row in the pivot col */ /* and compute the external column degree for each frontal */ /* ---------------------------------------------------------------------- */ for (i2 = Work->fscan_row ; i2 < fnrows ; i2++) { /* Get a row */ row = Work->NewRows [i2] ; if (row < 0) row = FLIP (row) ; ASSERT (row >= 0 && row < n_row) ; DEBUG6 (("SCAN1-row: "ID"\n", row)) ; #ifndef NDEBUG UMF_dump_rowcol (0, Numeric, Work, row, FALSE) ; #endif ASSERT (NON_PIVOTAL_ROW (row)) ; tpi = Row_tuples [row] ; if (!tpi) continue ; tp = (Tuple *) (Memory + tpi) ; tp1 = tp ; tp2 = tp ; tpend = tp + Row_tlen [row] ; for ( ; tp < tpend ; tp++) { e = tp->e ; ASSERT (e > 0 && e <= Work->nel) ; if (!E [e]) continue ; /* element already deallocated */ f = tp->f ; p = Memory + E [e] ; ep = (Element *) p ; p += UNITS (Element, 1) ; Rows = ((Int *) p) + ep->ncols ; if (Rows [f] == EMPTY) continue ; /* row already assembled */ ASSERT (row == Rows [f]) ; if (ep->cdeg < cdeg0) { /* first time seen in scan1-row */ ep->cdeg = ep->nrowsleft + cdeg0 ; DEBUG6 (("e "ID" First seen: cdeg: "ID" ", e, ep->cdeg-cdeg0)) ; ASSERT (ep->ncolsleft > 0 && ep->nrowsleft > 0) ; } ep->cdeg-- ; /* decrement external column degree */ DEBUG6 (("e "ID" New ext col deg: "ID"\n", e, ep->cdeg - cdeg0)) ; /* this element is not yet in the new son list */ if (ep->cdeg == cdeg0 && ep->next == EMPTY) { /* A new LUson or Uson has been found */ ep->next = son_list ; son_list = e ; } ASSERT (ep->cdeg >= cdeg0) ; *tp2++ = *tp ; /* leave the tuple in the list */ } Row_tlen [row] = tp2 - tp1 ; } /* ---------------------------------------------------------------------- */ /* SCAN1-col: scan the element lists of each new col in the pivot row */ /* and compute the external row degree for each frontal */ /* ---------------------------------------------------------------------- */ for (j2 = Work->fscan_col ; j2 < fncols ; j2++) { /* Get a column */ col = Work->NewCols [j2] ; if (col < 0) col = FLIP (col) ; ASSERT (col >= 0 && col < n_col) ; DEBUG6 (("SCAN 1-col: "ID"\n", col)) ; #ifndef NDEBUG UMF_dump_rowcol (1, Numeric, Work, col, FALSE) ; #endif ASSERT (NON_PIVOTAL_COL (col)) ; tpi = Col_tuples [col] ; if (!tpi) continue ; tp = (Tuple *) (Memory + tpi) ; tp1 = tp ; tp2 = tp ; tpend = tp + Col_tlen [col] ; for ( ; tp < tpend ; tp++) { e = tp->e ; ASSERT (e > 0 && e <= Work->nel) ; if (!E [e]) continue ; /* element already deallocated */ f = tp->f ; p = Memory + E [e] ; ep = (Element *) p ; p += UNITS (Element, 1) ; Cols = (Int *) p ; if (Cols [f] == EMPTY) continue ; /* column already assembled */ ASSERT (col == Cols [f]) ; if (ep->rdeg < rdeg0) { /* first time seen in scan1-col */ ep->rdeg = ep->ncolsleft + rdeg0 ; DEBUG6 (("e "ID" First seen: rdeg: "ID" ", e, ep->rdeg-rdeg0)) ; ASSERT (ep->ncolsleft > 0 && ep->nrowsleft > 0) ; } ep->rdeg-- ; /* decrement external row degree */ DEBUG6 (("e "ID" New ext row degree: "ID"\n", e, ep->rdeg-rdeg0)) ; if (ep->rdeg == rdeg0 && ep->next == EMPTY) { /* A new LUson or Lson has been found */ ep->next = son_list ; son_list = e ; } ASSERT (ep->rdeg >= rdeg0) ; *tp2++ = *tp ; /* leave the tuple in the list */ } Col_tlen [col] = tp2 - tp1 ; } /* ---------------------------------------------------------------------- */ /* assemble new sons via full scans */ /* ---------------------------------------------------------------------- */ next = EMPTY ; for (e = son_list ; e > 0 ; e = next) { ASSERT (e > 0 && e <= Work->nel && E [e]) ; p = Memory + E [e] ; DEBUG2 (("New son: "ID"\n", e)) ; #ifndef NDEBUG UMF_dump_element (Numeric, Work, e, FALSE) ; #endif GET_ELEMENT (ep, p, Cols, Rows, ncols, nrows, S) ; nrowsleft = ep->nrowsleft ; ncolsleft = ep->ncolsleft ; next = ep->next ; ep->next = EMPTY ; extrdeg = (ep->rdeg < rdeg0) ? ncolsleft : (ep->rdeg - rdeg0) ; extcdeg = (ep->cdeg < cdeg0) ? nrowsleft : (ep->cdeg - cdeg0) ; ncols_to_assemble = ncolsleft - extrdeg ; nrows_to_assemble = nrowsleft - extcdeg ; DEBUG2 (("extrdeg "ID" extcdeg "ID"\n", extrdeg, extcdeg)) ; if (extrdeg == 0 && extcdeg == 0) { /* -------------------------------------------------------------- */ /* this is an LUson - assemble an entire contribution block */ /* -------------------------------------------------------------- */ DEBUG6 (("LUson found: "ID"\n", e)) ; if (nrows == nrowsleft) { /* ---------------------------------------------------------- */ /* no rows assembled out of this LUson yet */ /* ---------------------------------------------------------- */ /* compute the compressed column offset vector*/ /* [ use Wm [0..nrows-1] for offsets */ #pragma ivdep for (i = 0 ; i < nrows ; i++) { row = Rows [i] ; Row_degree [row] -= ncolsleft ; Wm [i] = Frpos [row] ; } if (ncols == ncolsleft) { /* ------------------------------------------------------ */ /* no rows or cols assembled out of LUson yet */ /* ------------------------------------------------------ */ for (j = 0 ; j < ncols ; j++) { col = Cols [j] ; #ifndef FIXQ Col_degree [col] -= nrowsleft ; #endif Fcol = Fcblock + Fcpos [col] ; #pragma ivdep for (i = 0 ; i < nrows ; i++) { /* Fcol [Wm [i]] += S [i] ; */ ASSEMBLE (Fcol [Wm [i]], S [i]) ; } S += nrows ; } } else { /* ------------------------------------------------------ */ /* only cols have been assembled out of LUson */ /* ------------------------------------------------------ */ for (j = 0 ; j < ncols ; j++) { col = Cols [j] ; if (col >= 0) { #ifndef FIXQ Col_degree [col] -= nrowsleft ; #endif Fcol = Fcblock + Fcpos [col] ; #pragma ivdep for (i = 0 ; i < nrows ; i++) { /* Fcol [Wm [i]] += S [i] ; */ ASSEMBLE (Fcol [Wm [i]], S [i]) ; } } S += nrows ; } } /* ] done using Wm [0..nrows-1] for offsets */ } else { /* ---------------------------------------------------------- */ /* some rows have been assembled out of this LUson */ /* ---------------------------------------------------------- */ /* compute the compressed column offset vector*/ /* [ use Woo,Wm [0..nrowsleft-1] for offsets */ ngetrows = 0 ; for (i = 0 ; i < nrows ; i++) { row = Rows [i] ; if (row >= 0) { Row_degree [row] -= ncolsleft ; Woo [ngetrows] = i ; Wm [ngetrows++] = Frpos [row] ; } } ASSERT (ngetrows == nrowsleft) ; if (ncols == ncolsleft) { /* ------------------------------------------------------ */ /* only rows have been assembled out of this LUson */ /* ------------------------------------------------------ */ for (j = 0 ; j < ncols ; j++) { col = Cols [j] ; #ifndef FIXQ Col_degree [col] -= nrowsleft ; #endif Fcol = Fcblock + Fcpos [col] ; #pragma ivdep for (i = 0 ; i < nrowsleft ; i++) { /* Fcol [Wm [i]] += S [Woo [i]] ; */ ASSEMBLE (Fcol [Wm [i]], S [Woo [i]]) ; } S += nrows ; } } else { /* ------------------------------------------------------ */ /* both rows and columns have been assembled out of LUson */ /* ------------------------------------------------------ */ for (j = 0 ; j < ncols ; j++) { col = Cols [j] ; if (col >= 0) { #ifndef FIXQ Col_degree [col] -= nrowsleft ; #endif Fcol = Fcblock + Fcpos [col] ; #pragma ivdep for (i = 0 ; i < nrowsleft ; i++) { /* Fcol [Wm [i]] += S [Woo [i]] ; */ ASSEMBLE (Fcol [Wm [i]], S [Woo [i]]) ; } } S += nrows ; } } /* ] done using Woo,Wm [0..nrowsleft-1] */ } /* deallocate the element: remove from ordered list */ UMF_mem_free_tail_block (Numeric, E [e]) ; E [e] = 0 ; } else if (extcdeg == 0) { /* -------------------------------------------------------------- */ /* this is a Uson - assemble all possible columns */ /* -------------------------------------------------------------- */ DEBUG6 (("New USON: "ID"\n", e)) ; ASSERT (extrdeg > 0) ; DEBUG6 (("New uson "ID" cols to do "ID"\n", e, ncols_to_assemble)) ; if (ncols_to_assemble > 0) { Int skip = FALSE ; if (ncols_to_assemble * 16 < ncols && nrows == 1) { /* this is a tall and thin frontal matrix consisting of * only one column (most likely an original column). Do * not assemble it. It cannot be the pivot column, since * the pivot column element would be an LU son, not an Lson, * of the current frontal matrix. */ ASSERT (nrowsleft == 1) ; ASSERT (Rows [0] >= 0 && Rows [0] < Work->n_row) ; skip = TRUE ; Work->any_skip = TRUE ; } if (!skip) { if (nrows == nrowsleft) { /* -------------------------------------------------- */ /* no rows have been assembled out of this Uson yet */ /* -------------------------------------------------- */ /* compute the compressed column offset vector */ /* [ use Wm [0..nrows-1] for offsets */ #pragma ivdep for (i = 0 ; i < nrows ; i++) { row = Rows [i] ; ASSERT (row >= 0 && row < n_row) ; Row_degree [row] -= ncols_to_assemble ; Wm [i] = Frpos [row] ; } for (j = 0 ; j < ncols ; j++) { col = Cols [j] ; if ((col >= 0) && (Fcpos [col] >= 0)) { #ifndef FIXQ Col_degree [col] -= nrowsleft ; #endif Fcol = Fcblock + Fcpos [col] ; #pragma ivdep for (i = 0 ; i < nrows ; i++) { /* Fcol [Wm [i]] += S [i] ; */ ASSEMBLE (Fcol [Wm [i]], S [i]) ; } /* flag the column as assembled from Uson */ Cols [j] = EMPTY ; } S += nrows ; } /* ] done using Wm [0..nrows-1] for offsets */ } else { /* -------------------------------------------------- */ /* some rows have been assembled out of this Uson */ /* -------------------------------------------------- */ /* compute the compressed column offset vector*/ /* [ use Woo,Wm [0..nrows-1] for offsets */ ngetrows = 0 ; for (i = 0 ; i < nrows ; i++) { row = Rows [i] ; if (row >= 0) { Row_degree [row] -= ncols_to_assemble ; ASSERT (row < n_row && Frpos [row] >= 0) ; Woo [ngetrows] = i ; Wm [ngetrows++] = Frpos [row] ; } } ASSERT (ngetrows == nrowsleft) ; for (j = 0 ; j < ncols ; j++) { col = Cols [j] ; if ((col >= 0) && (Fcpos [col] >= 0)) { #ifndef FIXQ Col_degree [col] -= nrowsleft ; #endif Fcol = Fcblock + Fcpos [col] ; #pragma ivdep for (i = 0 ; i < nrowsleft ; i++) { /* Fcol [Wm [i]] += S [Woo [i]] ; */ ASSEMBLE (Fcol [Wm [i]], S [Woo [i]]) ; } /* flag the column as assembled from Uson */ Cols [j] = EMPTY ; } S += nrows ; } /* ] done using Woo,Wm */ } ep->ncolsleft = extrdeg ; } } } else { /* -------------------------------------------------------------- */ /* this is an Lson - assemble all possible rows */ /* -------------------------------------------------------------- */ DEBUG6 (("New LSON: "ID"\n", e)) ; ASSERT (extrdeg == 0 && extcdeg > 0) ; DEBUG6 (("New lson "ID" rows to do "ID"\n", e, nrows_to_assemble)) ; if (nrows_to_assemble > 0) { Int skip = FALSE ; if (nrows_to_assemble * 16 < nrows && ncols == 1) { /* this is a tall and thin frontal matrix consisting of * only one column (most likely an original column). Do * not assemble it. It cannot be the pivot column, since * the pivot column element would be an LU son, not an Lson, * of the current frontal matrix. */ ASSERT (ncolsleft == 1) ; ASSERT (Cols [0] >= 0 && Cols [0] < Work->n_col) ; Work->any_skip = TRUE ; skip = TRUE ; } if (!skip) { /* compute the compressed column offset vector */ /* [ use Woo,Wm [0..nrows-1] for offsets */ ngetrows = 0 ; for (i = 0 ; i < nrows ; i++) { row = Rows [i] ; if ((row >= 0) && (Frpos [row] >= 0)) { ASSERT (row < n_row) ; Row_degree [row] -= ncolsleft ; Woo [ngetrows] = i ; Wm [ngetrows++] = Frpos [row] ; /* flag the row as assembled from the Lson */ Rows [i] = EMPTY ; } } ASSERT (nrowsleft - ngetrows == extcdeg) ; ASSERT (ngetrows == nrows_to_assemble) ; if (ncols == ncolsleft) { /* -------------------------------------------------- */ /* no columns assembled out this Lson yet */ /* -------------------------------------------------- */ for (j = 0 ; j < ncols ; j++) { col = Cols [j] ; ASSERT (col >= 0 && col < n_col) ; #ifndef FIXQ Col_degree [col] -= nrows_to_assemble ; #endif Fcol = Fcblock + Fcpos [col] ; #pragma ivdep for (i = 0 ; i < nrows_to_assemble ; i++) { /* Fcol [Wm [i]] += S [Woo [i]] ; */ ASSEMBLE (Fcol [Wm [i]], S [Woo [i]]) ; } S += nrows ; } } else { /* -------------------------------------------------- */ /* some columns have been assembled out of this Lson */ /* -------------------------------------------------- */ for (j = 0 ; j < ncols ; j++) { col = Cols [j] ; ASSERT (col < n_col) ; if (col >= 0) { #ifndef FIXQ Col_degree [col] -= nrows_to_assemble ; #endif Fcol = Fcblock + Fcpos [col] ; #pragma ivdep for (i = 0 ; i < nrows_to_assemble ; i++) { /* Fcol [Wm [i]] += S [Woo [i]] ; */ ASSEMBLE (Fcol [Wm [i]], S [Woo [i]]) ; } } S += nrows ; } } /* ] done using Woo,Wm */ ep->nrowsleft = extcdeg ; } } } } /* Note that garbage collection, and build tuples */ /* both destroy the son list. */ /* ] son_list now empty */ /* ---------------------------------------------------------------------- */ /* If frontal matrix extended, assemble old L/Usons from new rows/cols */ /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ /* SCAN2-row: assemble rows of old Lsons from the new rows */ /* ---------------------------------------------------------------------- */ #ifndef NDEBUG DEBUG7 (("Current frontal matrix: (prior to scan2-row)\n")) ; UMF_dump_current_front (Numeric, Work, TRUE) ; #endif /* rescan the pivot row */ if (Work->any_skip) { row_assemble (Work->pivrow, Numeric, Work) ; } if (Work->do_scan2row) { for (i2 = Work->fscan_row ; i2 < fnrows ; i2++) { /* Get a row */ row = Work->NewRows [i2] ; if (row < 0) row = FLIP (row) ; ASSERT (row >= 0 && row < n_row) ; if (!(row == Work->pivrow && Work->any_skip)) { /* assemble it */ row_assemble (row, Numeric, Work) ; } } } /* ---------------------------------------------------------------------- */ /* SCAN2-col: assemble columns of old Usons from the new columns */ /* ---------------------------------------------------------------------- */ #ifndef NDEBUG DEBUG7 (("Current frontal matrix: (prior to scan2-col)\n")) ; UMF_dump_current_front (Numeric, Work, TRUE) ; #endif /* rescan the pivot col */ if (Work->any_skip) { col_assemble (Work->pivcol, Numeric, Work) ; } if (Work->do_scan2col) { for (j2 = Work->fscan_col ; j2 < fncols ; j2++) { /* Get a column */ col = Work->NewCols [j2] ; if (col < 0) col = FLIP (col) ; ASSERT (col >= 0 && col < n_col) ; if (!(col == Work->pivcol && Work->any_skip)) { /* assemble it */ col_assemble (col, Numeric, Work) ; } } } /* ---------------------------------------------------------------------- */ /* done. the remainder of this routine is used only when in debug mode */ /* ---------------------------------------------------------------------- */ #ifndef NDEBUG /* ---------------------------------------------------------------------- */ /* when debugging: make sure the assembly did everything that it could */ /* ---------------------------------------------------------------------- */ DEBUG3 (("::Assemble done\n")) ; for (i2 = 0 ; i2 < fnrows ; i2++) { /* Get a row */ row = Work->Frows [i2] ; ASSERT (row >= 0 && row < n_row) ; DEBUG6 (("DEBUG SCAN 1: "ID"\n", row)) ; UMF_dump_rowcol (0, Numeric, Work, row, TRUE) ; ASSERT (NON_PIVOTAL_ROW (row)) ; tpi = Row_tuples [row] ; if (!tpi) continue ; tp = (Tuple *) (Memory + tpi) ; tpend = tp + Row_tlen [row] ; for ( ; tp < tpend ; tp++) { e = tp->e ; ASSERT (e > 0 && e <= Work->nel) ; if (!E [e]) continue ; /* element already deallocated */ f = tp->f ; p = Memory + E [e] ; ep = (Element *) p ; p += UNITS (Element, 1) ; Cols = (Int *) p ; Rows = ((Int *) p) + ep->ncols ; if (Rows [f] == EMPTY) continue ; /* row already assembled */ ASSERT (row == Rows [f]) ; extrdeg = (ep->rdeg < rdeg0) ? ep->ncolsleft : (ep->rdeg - rdeg0) ; extcdeg = (ep->cdeg < cdeg0) ? ep->nrowsleft : (ep->cdeg - cdeg0) ; DEBUG6 (( "e "ID" After assembly ext row deg: "ID" ext col degree "ID"\n", e, extrdeg, extcdeg)) ; if (Work->any_skip) { /* no Lsons in any row, except for very tall and thin ones */ ASSERT (extrdeg >= 0) ; if (extrdeg == 0) { /* this is an unassemble Lson */ ASSERT (ep->ncols == 1) ; ASSERT (ep->ncolsleft == 1) ; col = Cols [0] ; ASSERT (col != Work->pivcol) ; } } else { /* no Lsons in any row */ ASSERT (extrdeg > 0) ; /* Uson external row degree is = number of cols left */ ASSERT (IMPLIES (extcdeg == 0, extrdeg == ep->ncolsleft)) ; } } } /* ---------------------------------------------------------------------- */ for (j2 = 0 ; j2 < fncols ; j2++) { /* Get a column */ col = Work->Fcols [j2] ; ASSERT (col >= 0 && col < n_col) ; DEBUG6 (("DEBUG SCAN 2: "ID"\n", col)) ; #ifndef FIXQ UMF_dump_rowcol (1, Numeric, Work, col, TRUE) ; #else UMF_dump_rowcol (1, Numeric, Work, col, FALSE) ; #endif ASSERT (NON_PIVOTAL_COL (col)) ; tpi = Col_tuples [col] ; if (!tpi) continue ; tp = (Tuple *) (Memory + tpi) ; tpend = tp + Col_tlen [col] ; for ( ; tp < tpend ; tp++) { e = tp->e ; ASSERT (e > 0 && e <= Work->nel) ; if (!E [e]) continue ; /* element already deallocated */ f = tp->f ; p = Memory + E [e] ; ep = (Element *) p ; p += UNITS (Element, 1) ; Cols = (Int *) p ; Rows = ((Int *) p) + ep->ncols ; if (Cols [f] == EMPTY) continue ; /* column already assembled */ ASSERT (col == Cols [f]) ; extrdeg = (ep->rdeg < rdeg0) ? ep->ncolsleft : (ep->rdeg - rdeg0) ; extcdeg = (ep->cdeg < cdeg0) ? ep->nrowsleft : (ep->cdeg - cdeg0) ; DEBUG6 (("e "ID" After assembly ext col deg: "ID"\n", e, extcdeg)) ; if (Work->any_skip) { /* no Usons in any column, except for very tall and thin ones */ ASSERT (extcdeg >= 0) ; if (extcdeg == 0) { /* this is an unassemble Uson */ ASSERT (ep->nrows == 1) ; ASSERT (ep->nrowsleft == 1) ; row = Rows [0] ; ASSERT (row != Work->pivrow) ; } } else { /* no Usons in any column */ ASSERT (extcdeg > 0) ; /* Lson external column degree is = number of rows left */ ASSERT (IMPLIES (extrdeg == 0, extcdeg == ep->nrowsleft)) ; } } } #endif /* NDEBUG */ }
PRIVATE void row_assemble ( Int row, NumericType *Numeric, WorkType *Work ) { Entry *S, *Fcblock, *Frow ; Int tpi, e, *E, *Fcpos, *Frpos, *Row_degree, *Row_tuples, *Row_tlen, rdeg0, f, nrows, ncols, *Rows, *Cols, col, ncolsleft, j ; Tuple *tp, *tp1, *tp2, *tpend ; Unit *Memory, *p ; Element *ep ; #ifndef FIXQ Int *Col_degree ; Col_degree = Numeric->Cperm ; #endif Row_tuples = Numeric->Uip ; tpi = Row_tuples [row] ; if (!tpi) return ; Memory = Numeric->Memory ; E = Work->E ; Fcpos = Work->Fcpos ; Frpos = Work->Frpos ; Row_degree = Numeric->Rperm ; Row_tlen = Numeric->Uilen ; E = Work->E ; Memory = Numeric->Memory ; rdeg0 = Work->rdeg0 ; Fcblock = Work->Fcblock ; #ifndef NDEBUG DEBUG6 (("SCAN2-row: "ID"\n", row)) ; UMF_dump_rowcol (0, Numeric, Work, row, FALSE) ; #endif ASSERT (NON_PIVOTAL_ROW (row)) ; tp = (Tuple *) (Memory + tpi) ; tp1 = tp ; tp2 = tp ; tpend = tp + Row_tlen [row] ; for ( ; tp < tpend ; tp++) { e = tp->e ; ASSERT (e > 0 && e <= Work->nel) ; if (!E [e]) continue ; /* element already deallocated */ f = tp->f ; p = Memory + E [e] ; ep = (Element *) p ; p += UNITS (Element, 1) ; Cols = (Int *) p ; Rows = Cols + ep->ncols ; if (Rows [f] == EMPTY) continue ; /* row already assembled */ ASSERT (row == Rows [f] && row >= 0 && row < Work->n_row) ; if (ep->rdeg == rdeg0) { /* ------------------------------------------------------ */ /* this is an old Lson - assemble just one row */ /* ------------------------------------------------------ */ /* flag the row as assembled from the Lson */ Rows [f] = EMPTY ; nrows = ep->nrows ; ncols = ep->ncols ; p += UNITS (Int, ncols + nrows) ; S = ((Entry *) p) + f ; DEBUG6 (("Old LSON: "ID"\n", e)) ; #ifndef NDEBUG UMF_dump_element (Numeric, Work, e, FALSE) ; #endif ncolsleft = ep->ncolsleft ; Frow = Fcblock + Frpos [row] ; DEBUG6 (("LSON found (in scan2-row): "ID"\n", e)) ; Row_degree [row] -= ncolsleft ; if (ncols == ncolsleft) { /* -------------------------------------------------- */ /* no columns assembled out this Lson yet */ /* -------------------------------------------------- */ #pragma ivdep for (j = 0 ; j < ncols ; j++) { col = Cols [j] ; ASSERT (col >= 0 && col < Work->n_col) ; #ifndef FIXQ Col_degree [col] -- ; #endif /* Frow [Fcpos [col]] += *S ; */ ASSEMBLE (Frow [Fcpos [col]], *S) ; S += nrows ; } } else { /* -------------------------------------------------- */ /* some columns have been assembled out of this Lson */ /* -------------------------------------------------- */ #pragma ivdep for (j = 0 ; j < ncols ; j++) { col = Cols [j] ; if (col >= 0) { ASSERT (col < Work->n_col) ; #ifndef FIXQ Col_degree [col] -- ; #endif /* Frow [Fcpos [col]] += *S ; */ ASSEMBLE (Frow [Fcpos [col]], *S) ; } S += nrows ; } } ep->nrowsleft-- ; ASSERT (ep->nrowsleft > 0) ; } else { *tp2++ = *tp ; /* leave the tuple in the list */ } } Row_tlen [row] = tp2 - tp1 ; #ifndef NDEBUG DEBUG7 (("row assembled in scan2-row: "ID"\n", row)) ; UMF_dump_rowcol (0, Numeric, Work, row, FALSE) ; DEBUG7 (("Current frontal matrix: (scan 1b)\n")) ; UMF_dump_current_front (Numeric, Work, TRUE) ; #endif }
PRIVATE void col_assemble ( Int col, NumericType *Numeric, WorkType *Work ) { Entry *S, *Fcblock, *Fcol ; Int tpi, e, *E, *Fcpos, *Frpos, *Row_degree, *Col_tuples, *Col_tlen, cdeg0, f, nrows, ncols, *Rows, *Cols, row, nrowsleft, i ; Tuple *tp, *tp1, *tp2, *tpend ; Unit *Memory, *p ; Element *ep ; #if !defined (FIXQ) || !defined (NDEBUG) Int *Col_degree ; Col_degree = Numeric->Cperm ; #endif Col_tuples = Numeric->Lip ; tpi = Col_tuples [col] ; if (!tpi) return ; Memory = Numeric->Memory ; E = Work->E ; Fcpos = Work->Fcpos ; Frpos = Work->Frpos ; Row_degree = Numeric->Rperm ; Col_tlen = Numeric->Lilen ; E = Work->E ; Memory = Numeric->Memory ; cdeg0 = Work->cdeg0 ; Fcblock = Work->Fcblock ; DEBUG6 (("SCAN2-col: "ID"\n", col)) ; #ifndef NDEBUG UMF_dump_rowcol (1, Numeric, Work, col, FALSE) ; #endif ASSERT (NON_PIVOTAL_COL (col)) ; tp = (Tuple *) (Memory + tpi) ; tp1 = tp ; tp2 = tp ; tpend = tp + Col_tlen [col] ; for ( ; tp < tpend ; tp++) { e = tp->e ; ASSERT (e > 0 && e <= Work->nel) ; if (!E [e]) continue ; /* element already deallocated */ f = tp->f ; p = Memory + E [e] ; ep = (Element *) p ; p += UNITS (Element, 1) ; Cols = (Int *) p ; if (Cols [f] == EMPTY) continue ; /* col already assembled */ ASSERT (col == Cols [f] && col >= 0 && col < Work->n_col) ; if (ep->cdeg == cdeg0) { /* ------------------------------------------------------ */ /* this is an old Uson - assemble just one col */ /* ------------------------------------------------------ */ /* flag the col as assembled from the Uson */ Cols [f] = EMPTY ; nrows = ep->nrows ; ncols = ep->ncols ; Rows = Cols + ncols ; p += UNITS (Int, ncols + nrows) ; S = ((Entry *) p) + f * nrows ; DEBUG6 (("Old USON: "ID"\n", e)) ; #ifndef NDEBUG UMF_dump_element (Numeric, Work, e, FALSE) ; #endif nrowsleft = ep->nrowsleft ; Fcol = Fcblock + Fcpos [col] ; DEBUG6 (("USON found (in scan2-col): "ID"\n", e)) ; #ifndef FIXQ Col_degree [col] -= nrowsleft ; #endif if (nrows == nrowsleft) { /* -------------------------------------------------- */ /* no rows assembled out of this Uson yet */ /* -------------------------------------------------- */ #pragma ivdep for (i = 0 ; i < nrows ; i++) { row = Rows [i] ; ASSERT (row >= 0 && row < Work->n_row) ; Row_degree [row]-- ; /* Fcol [Frpos [row]] += S [i] ; */ ASSEMBLE (Fcol [Frpos [row]], S [i]) ; } } else { /* -------------------------------------------------- */ /* some rows have been assembled out of this Uson */ /* -------------------------------------------------- */ #pragma ivdep for (i = 0 ; i < nrows ; i++) { row = Rows [i] ; if (row >= 0) { ASSERT (row < Work->n_row) ; Row_degree [row]-- ; /* Fcol [Frpos [row]] += S [i] ; */ ASSEMBLE (Fcol [Frpos [row]], S [i]) ; } } } ep->ncolsleft-- ; ASSERT (ep->ncolsleft > 0) ; } else { *tp2++ = *tp ; /* leave the tuple in the list */ } } Col_tlen [col] = tp2 - tp1 ; #ifndef NDEBUG DEBUG7 (("Column assembled in scan2-col: "ID"\n", col)) ; UMF_dump_rowcol (1, Numeric, Work, col, FALSE) ; DEBUG7 (("Current frontal matrix: after scan2-col\n")) ; UMF_dump_current_front (Numeric, Work, TRUE) ; #endif }
GLOBAL Int UMF_extend_front ( NumericType *Numeric, WorkType *Work ) { /* ---------------------------------------------------------------------- */ /* local variables */ /* ---------------------------------------------------------------------- */ Int j, i, *Frows, row, col, *Wrow, fnr2, fnc2, *Frpos, *Fcpos, *Fcols, fnrows_extended, rrdeg, ccdeg, fncols_extended, fnr_curr, fnc_curr, fnrows, fncols, pos, fnpiv, *Wm ; Entry *Wx, *Wy, *Fu, *Fl ; /* ---------------------------------------------------------------------- */ /* get current frontal matrix and check for frontal growth */ /* ---------------------------------------------------------------------- */ fnpiv = Work->fnpiv ; #ifndef NDEBUG DEBUG2 (("EXTEND FRONT\n")) ; DEBUG2 (("Work->fnpiv "ID"\n", fnpiv)) ; ASSERT (Work->Flblock == Work->Flublock + Work->nb*Work->nb) ; ASSERT (Work->Fublock == Work->Flblock + Work->fnr_curr*Work->nb) ; ASSERT (Work->Fcblock == Work->Fublock + Work->nb*Work->fnc_curr) ; DEBUG7 (("C block: ")) ; UMF_dump_dense (Work->Fcblock, Work->fnr_curr, Work->fnrows, Work->fncols) ; DEBUG7 (("L block: ")) ; UMF_dump_dense (Work->Flblock, Work->fnr_curr, Work->fnrows, fnpiv); DEBUG7 (("U' block: ")) ; UMF_dump_dense (Work->Fublock, Work->fnc_curr, Work->fncols, fnpiv) ; DEBUG7 (("LU block: ")) ; UMF_dump_dense (Work->Flublock, Work->nb, fnpiv, fnpiv) ; #endif if (Work->do_grow) { fnr2 = UMF_FRONTAL_GROWTH * Work->fnrows_new + 2 ; fnc2 = UMF_FRONTAL_GROWTH * Work->fncols_new + 2 ; if (!UMF_grow_front (Numeric, fnr2, fnc2, Work, 1)) { DEBUGm4 (("out of memory: extend front\n")) ; return (FALSE) ; } } fnr_curr = Work->fnr_curr ; fnc_curr = Work->fnc_curr ; ASSERT (Work->fnrows_new + 1 <= fnr_curr) ; ASSERT (Work->fncols_new + 1 <= fnc_curr) ; ASSERT (fnr_curr >= 0 && fnr_curr % 2 == 1) ; /* ---------------------------------------------------------------------- */ /* get parameters */ /* ---------------------------------------------------------------------- */ Frows = Work->Frows ; Frpos = Work->Frpos ; Fcols = Work->Fcols ; Fcpos = Work->Fcpos ; fnrows = Work->fnrows ; fncols = Work->fncols ; rrdeg = Work->rrdeg ; ccdeg = Work->ccdeg ; /* scan starts at the first new column in Fcols */ /* also scan the pivot column if it was not in the front */ Work->fscan_col = fncols ; Work->NewCols = Fcols ; /* scan1 starts at the first new row in Frows */ /* also scan the pivot row if it was not in the front */ Work->fscan_row = fnrows ; Work->NewRows = Frows ; /* ---------------------------------------------------------------------- */ /* extend row pattern of the front with the new pivot column */ /* ---------------------------------------------------------------------- */ fnrows_extended = fnrows ; fncols_extended = fncols ; #ifndef NDEBUG DEBUG2 (("Pivot col, before extension: "ID"\n", fnrows)) ; for (i = 0 ; i < fnrows ; i++) { DEBUG2 ((" "ID": row "ID"\n", i, Frows [i])) ; ASSERT (Frpos [Frows [i]] == i) ; } DEBUG2 (("Extending pivot column: pivcol_in_front: "ID"\n", Work->pivcol_in_front)) ; #endif Fl = Work->Flblock + fnpiv * fnr_curr ; if (Work->pivcol_in_front) { /* extended pattern and position already in Frows, Frpos. Values above * the diagonal are already in LU block. Values on and below the * diagonal are in Wy [0 .. fnrows_extended-1]. Copy into the L * block. */ fnrows_extended += ccdeg ; Wy = Work->Wy ; for (i = 0 ; i < fnrows_extended ; i++) { Fl [i] = Wy [i] ; #ifndef NDEBUG row = Frows [i] ; DEBUG2 ((" "ID": row "ID" ", i, row)) ; EDEBUG2 (Fl [i]) ; if (row == Work->pivrow) DEBUG2 ((" <- pivrow")) ; DEBUG2 (("\n")) ; if (i == fnrows - 1) DEBUG2 ((" :::::::\n")) ; ASSERT (row >= 0 && row < Work->n_row) ; ASSERT (Frpos [row] == i) ; #endif } } else { /* extended pattern,values is in (Wm,Wx), not yet in the front */ Entry *F ; Fu = Work->Flublock + fnpiv * Work->nb ; Wm = Work->Wm ; Wx = Work->Wx ; F = Fu ; for (i = 0 ; i < fnpiv ; i++) { CLEAR_AND_INCREMENT (F) ; } F = Fl ; for (i = 0 ; i < fnrows ; i++) { CLEAR_AND_INCREMENT (F) ; } for (i = 0 ; i < ccdeg ; i++) { row = Wm [i] ; #ifndef NDEBUG DEBUG2 ((" "ID": row "ID" (ext) ", fnrows_extended, row)) ; EDEBUG2 (Wx [i]) ; if (row == Work->pivrow) DEBUG2 ((" <- pivrow")) ; DEBUG2 (("\n")) ; ASSERT (row >= 0 && row < Work->n_row) ; #endif pos = Frpos [row] ; if (pos < 0) { pos = fnrows_extended++ ; Frows [pos] = row ; Frpos [row] = pos ; } Fl [pos] = Wx [i] ; } } ASSERT (fnrows_extended <= fnr_curr) ; /* ---------------------------------------------------------------------- */ /* extend the column pattern of the front with the new pivot row */ /* ---------------------------------------------------------------------- */ #ifndef NDEBUG DEBUG6 (("Pivot row, before extension: "ID"\n", fncols)) ; for (j = 0 ; j < fncols ; j++) { DEBUG7 ((" "ID": col "ID"\n", j, Fcols [j])) ; ASSERT (Fcpos [Fcols [j]] == j * fnr_curr) ; } DEBUG6 (("Extending pivot row:\n")) ; #endif if (Work->pivrow_in_front) { if (Work->pivcol_in_front) { ASSERT (Fcols == Work->Wrow) ; for (j = fncols ; j < rrdeg ; j++) { #ifndef NDEBUG col = Fcols [j] ; DEBUG2 ((" "ID": col "ID" (ext)\n", j, col)) ; ASSERT (col != Work->pivcol) ; ASSERT (col >= 0 && col < Work->n_col) ; ASSERT (Fcpos [col] < 0) ; #endif Fcpos [Fcols [j]] = j * fnr_curr ; } } else { /* OUT-IN option: pivcol not in front, but pivrow is in front */ Wrow = Work->Wrow ; ASSERT (IMPLIES (Work->pivcol_in_front, Wrow == Fcols)) ; if (Wrow == Fcols) { /* Wrow and Fcols are equivalenced */ for (j = fncols ; j < rrdeg ; j++) { col = Wrow [j] ; DEBUG2 ((" "ID": col "ID" (ext)\n", j, col)) ; ASSERT (Fcpos [col] < 0) ; /* Fcols [j] = col ; not needed */ Fcpos [col] = j * fnr_curr ; } } else { for (j = fncols ; j < rrdeg ; j++) { col = Wrow [j] ; DEBUG2 ((" "ID": col "ID" (ext)\n", j, col)) ; ASSERT (Fcpos [col] < 0) ; Fcols [j] = col ; Fcpos [col] = j * fnr_curr ; } } } fncols_extended = rrdeg ; } else { ASSERT (Fcols != Work->Wrow) ; Wrow = Work->Wrow ; for (j = 0 ; j < rrdeg ; j++) { col = Wrow [j] ; ASSERT (col >= 0 && col < Work->n_col) ; if (Fcpos [col] < 0) { DEBUG2 ((" col:: "ID" (ext)\n", col)) ; Fcols [fncols_extended] = col ; Fcpos [col] = fncols_extended * fnr_curr ; fncols_extended++ ; } } } /* ---------------------------------------------------------------------- */ /* pivot row and column have been extended */ /* ---------------------------------------------------------------------- */ #ifndef NDEBUG ASSERT (fncols_extended <= fnc_curr) ; ASSERT (fnrows_extended <= fnr_curr) ; DEBUG6 (("Pivot col, after ext: "ID" "ID"\n", fnrows,fnrows_extended)) ; for (i = 0 ; i < fnrows_extended ; i++) { row = Frows [i] ; DEBUG7 ((" "ID": row "ID" pos "ID" old: %d", i, row, Frpos [row], i < fnrows)) ; if (row == Work->pivrow ) DEBUG7 ((" <-- pivrow")) ; DEBUG7 (("\n")) ; ASSERT (Frpos [Frows [i]] == i) ; } DEBUG6 (("Pivot row position: "ID"\n", Frpos [Work->pivrow])) ; ASSERT (Frpos [Work->pivrow] >= 0) ; ASSERT (Frpos [Work->pivrow] < fnrows_extended) ; DEBUG6 (("Pivot row, after ext: "ID" "ID"\n", fncols,fncols_extended)) ; for (j = 0 ; j < fncols_extended ; j++) { col = Fcols [j] ; DEBUG7 ((" "ID": col "ID" pos "ID" old: %d", j, col, Fcpos [col], j < fncols)) ; if (col == Work->pivcol ) DEBUG7 ((" <-- pivcol")) ; DEBUG7 (("\n")) ; ASSERT (Fcpos [Fcols [j]] == j * fnr_curr) ; } DEBUG6 (("Pivot col position: "ID"\n", Fcpos [Work->pivcol])) ; ASSERT (Fcpos [Work->pivcol] >= 0) ; ASSERT (Fcpos [Work->pivcol] < fncols_extended * fnr_curr) ; #endif /* ---------------------------------------------------------------------- */ /* Zero the newly extended frontal matrix */ /* ---------------------------------------------------------------------- */ zero_front (Work->Flblock, Work->Fublock, Work->Fcblock, fnrows, fncols, fnr_curr, fnc_curr, fnpiv, fnrows_extended, fncols_extended) ; /* ---------------------------------------------------------------------- */ /* finalize extended row and column pattern of the frontal matrix */ /* ---------------------------------------------------------------------- */ Work->fnrows = fnrows_extended ; Work->fncols = fncols_extended ; ASSERT (fnrows_extended == Work->fnrows_new + 1) ; ASSERT (fncols_extended == Work->fncols_new + 1) ; return (TRUE) ; }
PRIVATE void get_U ( Int Up [ ], /* of size n_col+1 */ Int Ui [ ], /* of size unz, where unz = Up [n_col] */ double Ux [ ], /* of size unz */ #ifdef COMPLEX double Uz [ ], /* of size unz */ #endif NumericType *Numeric, Int Pattern [ ], /* workspace of size n_col */ Int Wi [ ] /* workspace of size n_col */ ) { /* ---------------------------------------------------------------------- */ /* local variables */ /* ---------------------------------------------------------------------- */ Entry value ; Entry *xp, *D, *Uval ; Int deg, j, *ip, col, *Upos, *Uilen, *Uip, n_col, ulen, *Usi, unz2, p, k, up, newUchain, pos, npiv, n1 ; #ifdef COMPLEX Int split = SPLIT (Uz) ; #endif #ifndef NDEBUG Int nnzpiv = 0 ; #endif /* ---------------------------------------------------------------------- */ /* get parameters */ /* ---------------------------------------------------------------------- */ DEBUG4 (("get_U start:\n")) ; n_col = Numeric->n_col ; n1 = Numeric->n1 ; npiv = Numeric->npiv ; Upos = Numeric->Upos ; Uilen = Numeric->Uilen ; Uip = Numeric->Uip ; D = Numeric->D ; /* ---------------------------------------------------------------------- */ /* count the nonzeros in each column of U */ /* ---------------------------------------------------------------------- */ for (col = 0 ; col < npiv ; col++) { /* include the diagonal entry in the column counts */ DEBUG4 (("D ["ID"] = ", col)) ; EDEBUG4 (D [col]) ; Wi [col] = IS_NONZERO (D [col]) ; DEBUG4 ((" is nonzero: "ID"\n", Wi [col])) ; #ifndef NDEBUG nnzpiv += IS_NONZERO (D [col]) ; #endif } DEBUG4 (("nnzpiv "ID" "ID"\n", nnzpiv, Numeric->nnzpiv)) ; ASSERT (nnzpiv == Numeric->nnzpiv) ; for (col = npiv ; col < n_col ; col++) { /* diagonal entries are zero for structurally singular part */ Wi [col] = 0 ; } deg = Numeric->ulen ; if (deg > 0) { /* make last pivot row of U (singular matrices only) */ DEBUG0 (("Last pivot row of U: ulen "ID"\n", deg)) ; for (j = 0 ; j < deg ; j++) { Pattern [j] = Numeric->Upattern [j] ; DEBUG0 ((" column "ID"\n", Pattern [j])) ; } } /* non-singletons */ for (k = npiv-1 ; k >= n1 ; k--) { /* ------------------------------------------------------------------ */ /* use row k of U */ /* ------------------------------------------------------------------ */ up = Uip [k] ; ulen = Uilen [k] ; newUchain = (up < 0) ; if (newUchain) { up = -up ; xp = (Entry *) (Numeric->Memory + up + UNITS (Int, ulen)) ; } else { xp = (Entry *) (Numeric->Memory + up) ; } for (j = 0 ; j < deg ; j++) { DEBUG4 ((" k "ID" col "ID" value\n", k, Pattern [j])) ; col = Pattern [j] ; ASSERT (col >= 0 && col < n_col) ; value = *xp++ ; EDEBUG4 (value) ; DEBUG4 (("\n")) ; if (IS_NONZERO (value)) { Wi [col]++ ; } } /* ------------------------------------------------------------------ */ /* make row k-1 of U in Pattern [0..deg-1] */ /* ------------------------------------------------------------------ */ if (k == n1) break ; if (newUchain) { /* next row is a new Uchain */ deg = ulen ; DEBUG4 (("end of chain for row of U "ID" deg "ID"\n", k-1, deg)) ; ip = (Int *) (Numeric->Memory + up) ; for (j = 0 ; j < deg ; j++) { col = *ip++ ; DEBUG4 ((" k "ID" col "ID"\n", k-1, col)) ; ASSERT (k <= col) ; Pattern [j] = col ; } } else { deg -= ulen ; DEBUG4 (("middle of chain for row of U "ID" deg "ID"\n", k-1, deg)); ASSERT (deg >= 0) ; pos = Upos [k] ; if (pos != EMPTY) { /* add the pivot column */ DEBUG4 (("k "ID" add pivot entry at position "ID"\n", k, pos)) ; ASSERT (pos >= 0 && pos <= deg) ; Pattern [deg++] = Pattern [pos] ; Pattern [pos] = k ; } } } /* singletons */ for (k = n1 - 1 ; k >= 0 ; k--) { deg = Uilen [k] ; DEBUG4 (("Singleton k "ID"\n", k)) ; if (deg > 0) { up = Uip [k] ; Usi = (Int *) (Numeric->Memory + up) ; up += UNITS (Int, deg) ; Uval = (Entry *) (Numeric->Memory + up) ; for (j = 0 ; j < deg ; j++) { col = Usi [j] ; value = Uval [j] ; DEBUG4 ((" k "ID" col "ID" value", k, col)) ; EDEBUG4 (value) ; DEBUG4 (("\n")) ; if (IS_NONZERO (value)) { Wi [col]++ ; } } } } /* ---------------------------------------------------------------------- */ /* construct the final column form of U */ /* ---------------------------------------------------------------------- */ /* create the column pointers */ unz2 = 0 ; for (col = 0 ; col < n_col ; col++) { Up [col] = unz2 ; unz2 += Wi [col] ; } Up [n_col] = unz2 ; DEBUG1 (("Numeric->unz "ID" npiv "ID" nnzpiv "ID" unz2 "ID"\n", Numeric->unz, npiv, Numeric->nnzpiv, unz2)) ; ASSERT (Numeric->unz + Numeric->nnzpiv == unz2) ; for (col = 0 ; col < n_col ; col++) { Wi [col] = Up [col+1] ; } /* add all of the diagonal entries */ for (col = 0 ; col < npiv ; col++) { if (IS_NONZERO (D [col])) { p = --(Wi [col]) ; Ui [p] = col ; #ifdef COMPLEX if (split) { Ux [p] = REAL_COMPONENT (D [col]) ; Uz [p] = IMAG_COMPONENT (D [col]) ; } else { Ux [2*p ] = REAL_COMPONENT (D [col]) ; Ux [2*p+1] = IMAG_COMPONENT (D [col]) ; } #else Ux [p] = D [col] ; #endif } } /* add all the entries from the rows of U */ deg = Numeric->ulen ; if (deg > 0) { /* make last pivot row of U (singular matrices only) */ for (j = 0 ; j < deg ; j++) { Pattern [j] = Numeric->Upattern [j] ; } } /* non-singletons */ for (k = npiv-1 ; k >= n1 ; k--) { /* ------------------------------------------------------------------ */ /* use row k of U */ /* ------------------------------------------------------------------ */ up = Uip [k] ; ulen = Uilen [k] ; newUchain = (up < 0) ; if (newUchain) { up = -up ; xp = (Entry *) (Numeric->Memory + up + UNITS (Int, ulen)) ; } else { xp = (Entry *) (Numeric->Memory + up) ; } xp += deg ; for (j = deg-1 ; j >= 0 ; j--) { DEBUG4 ((" k "ID" col "ID" value", k, Pattern [j])) ; col = Pattern [j] ; ASSERT (col >= 0 && col < n_col) ; value = *(--xp) ; EDEBUG4 (value) ; DEBUG4 (("\n")) ; if (IS_NONZERO (value)) { p = --(Wi [col]) ; Ui [p] = k ; #ifdef COMPLEX if (split) { Ux [p] = REAL_COMPONENT (value) ; Uz [p] = IMAG_COMPONENT (value) ; } else { Ux [2*p ] = REAL_COMPONENT (value) ; Ux [2*p+1] = IMAG_COMPONENT (value) ; } #else Ux [p] = value ; #endif } } /* ------------------------------------------------------------------ */ /* make row k-1 of U in Pattern [0..deg-1] */ /* ------------------------------------------------------------------ */ if (newUchain) { /* next row is a new Uchain */ deg = ulen ; DEBUG4 (("end of chain for row of U "ID" deg "ID"\n", k-1, deg)) ; ip = (Int *) (Numeric->Memory + up) ; for (j = 0 ; j < deg ; j++) { col = *ip++ ; DEBUG4 ((" k "ID" col "ID"\n", k-1, col)) ; ASSERT (k <= col) ; Pattern [j] = col ; } } else { deg -= ulen ; DEBUG4 (("middle of chain for row of U "ID" deg "ID"\n", k-1, deg)); ASSERT (deg >= 0) ; pos = Upos [k] ; if (pos != EMPTY) { /* add the pivot column */ DEBUG4 (("k "ID" add pivot entry at position "ID"\n", k, pos)) ; ASSERT (pos >= 0 && pos <= deg) ; Pattern [deg++] = Pattern [pos] ; Pattern [pos] = k ; } } } /* singletons */ for (k = n1 - 1 ; k >= 0 ; k--) { deg = Uilen [k] ; DEBUG4 (("Singleton k "ID"\n", k)) ; if (deg > 0) { up = Uip [k] ; Usi = (Int *) (Numeric->Memory + up) ; up += UNITS (Int, deg) ; Uval = (Entry *) (Numeric->Memory + up) ; for (j = 0 ; j < deg ; j++) { col = Usi [j] ; value = Uval [j] ; DEBUG4 ((" k "ID" col "ID" value", k, col)) ; EDEBUG4 (value) ; DEBUG4 (("\n")) ; if (IS_NONZERO (value)) { p = --(Wi [col]) ; Ui [p] = k ; #ifdef COMPLEX if (split) { Ux [p] = REAL_COMPONENT (value) ; Uz [p] = IMAG_COMPONENT (value) ; } else { Ux [2*p ] = REAL_COMPONENT (value) ; Ux [2*p+1] = IMAG_COMPONENT (value) ; } #else Ux [p] = value ; #endif } } } } #ifndef NDEBUG DEBUG6 (("U matrix:")) ; UMF_dump_col_matrix (Ux, #ifdef COMPLEX Uz, #endif Ui, Up, Numeric->n_row, n_col, Numeric->unz + Numeric->nnzpiv) ; #endif }
GLOBAL void UMF_scale_column ( NumericType *Numeric, WorkType *Work ) { /* ---------------------------------------------------------------------- */ /* local variables */ /* ---------------------------------------------------------------------- */ Entry pivot_value ; Entry *Fcol, *Flublock, *Flblock, *Fublock, *Fcblock ; Int k, k1, fnr_curr, fnrows, fncols, *Frpos, *Fcpos, pivrow, pivcol, *Frows, *Fcols, fnc_curr, fnpiv, *Row_tuples, nb, *Col_tuples, *Rperm, *Cperm, fspos, col2, row2 ; #ifndef NDEBUG Int *Col_degree, *Row_degree ; #endif /* ---------------------------------------------------------------------- */ /* get parameters */ /* ---------------------------------------------------------------------- */ fnrows = Work->fnrows ; fncols = Work->fncols ; fnpiv = Work->fnpiv ; /* ---------------------------------------------------------------------- */ Rperm = Numeric->Rperm ; Cperm = Numeric->Cperm ; /* ---------------------------------------------------------------------- */ Flublock = Work->Flublock ; Flblock = Work->Flblock ; Fublock = Work->Fublock ; Fcblock = Work->Fcblock ; fnr_curr = Work->fnr_curr ; fnc_curr = Work->fnc_curr ; Frpos = Work->Frpos ; Fcpos = Work->Fcpos ; Frows = Work->Frows ; Fcols = Work->Fcols ; pivrow = Work->pivrow ; pivcol = Work->pivcol ; ASSERT (pivrow >= 0 && pivrow < Work->n_row) ; ASSERT (pivcol >= 0 && pivcol < Work->n_col) ; #ifndef NDEBUG Col_degree = Numeric->Cperm ; /* for NON_PIVOTAL_COL macro */ Row_degree = Numeric->Rperm ; /* for NON_PIVOTAL_ROW macro */ #endif Row_tuples = Numeric->Uip ; Col_tuples = Numeric->Lip ; nb = Work->nb ; #ifndef NDEBUG ASSERT (fnrows == Work->fnrows_new + 1) ; ASSERT (fncols == Work->fncols_new + 1) ; DEBUG1 (("SCALE COL: fnrows "ID" fncols "ID"\n", fnrows, fncols)) ; DEBUG2 (("\nFrontal matrix, including all space:\n" "fnr_curr "ID" fnc_curr "ID" nb "ID"\n" "fnrows "ID" fncols "ID" fnpiv "ID"\n", fnr_curr, fnc_curr, nb, fnrows, fncols, fnpiv)) ; DEBUG2 (("\nJust the active part:\n")) ; DEBUG7 (("C block: ")) ; UMF_dump_dense (Fcblock, fnr_curr, fnrows, fncols) ; DEBUG7 (("L block: ")) ; UMF_dump_dense (Flblock, fnr_curr, fnrows, fnpiv); DEBUG7 (("U' block: ")) ; UMF_dump_dense (Fublock, fnc_curr, fncols, fnpiv) ; DEBUG7 (("LU block: ")) ; UMF_dump_dense (Flublock, nb, fnpiv, fnpiv) ; #endif /* ====================================================================== */ /* === Shift pivot row and column ======================================= */ /* ====================================================================== */ /* ---------------------------------------------------------------------- */ /* move pivot column into place */ /* ---------------------------------------------------------------------- */ /* Note that the pivot column is already in place. Just shift the last * column into the position vacated by the pivot column. */ fspos = Fcpos [pivcol] ; /* one less column in the contribution block */ fncols = --(Work->fncols) ; if (fspos != fncols * fnr_curr) { Int fs = fspos / fnr_curr ; DEBUG6 (("Shift pivot column in front\n")) ; DEBUG6 (("fspos: "ID" flpos: "ID"\n", fspos, fncols * fnr_curr)) ; /* ------------------------------------------------------------------ */ /* move Fe => Fs */ /* ------------------------------------------------------------------ */ /* column of the contribution block: */ { /* Fs: current position of pivot column in contribution block */ /* Fe: position of last column in contribution block */ Int i ; Entry *Fs, *Fe ; Fs = Fcblock + fspos ; Fe = Fcblock + fncols * fnr_curr ; #pragma ivdep for (i = 0 ; i < fnrows ; i++) { Fs [i] = Fe [i] ; } } /* column of the U2 block */ { /* Fs: current position of pivot column in U block */ /* Fe: last column in U block */ Int i ; Entry *Fs, *Fe ; Fs = Fublock + fs ; Fe = Fublock + fncols ; #pragma ivdep for (i = 0 ; i < fnpiv ; i++) { Fs [i * fnc_curr] = Fe [i * fnc_curr] ; } } /* move column Fe to Fs in the Fcols pattern */ col2 = Fcols [fncols] ; Fcols [fs] = col2 ; Fcpos [col2] = fspos ; } /* pivot column is no longer in the frontal matrix */ Fcpos [pivcol] = EMPTY ; #ifndef NDEBUG DEBUG2 (("\nFrontal matrix after col swap, including all space:\n" "fnr_curr "ID" fnc_curr "ID" nb "ID"\n" "fnrows "ID" fncols "ID" fnpiv "ID"\n", fnr_curr, fnc_curr, nb, fnrows, fncols, fnpiv)) ; DEBUG2 (("\nJust the active part:\n")) ; DEBUG7 (("C block: ")) ; UMF_dump_dense (Fcblock, fnr_curr, fnrows, fncols) ; DEBUG7 (("L block: ")) ; UMF_dump_dense (Flblock, fnr_curr, fnrows, fnpiv+1); DEBUG7 (("U' block: ")) ; UMF_dump_dense (Fublock, fnc_curr, fncols, fnpiv) ; DEBUG7 (("LU block: ")) ; UMF_dump_dense (Flublock, nb, fnpiv, fnpiv+1) ; #endif /* ---------------------------------------------------------------------- */ /* move pivot row into place */ /* ---------------------------------------------------------------------- */ fspos = Frpos [pivrow] ; /* one less row in the contribution block */ fnrows = --(Work->fnrows) ; DEBUG6 (("Swap/shift pivot row in front:\n")) ; DEBUG6 (("fspos: "ID" flpos: "ID"\n", fspos, fnrows)) ; if (fspos == fnrows) { /* ------------------------------------------------------------------ */ /* move Fs => Fd */ /* ------------------------------------------------------------------ */ DEBUG6 (("row case 1\n")) ; /* row of the contribution block: */ { Int j ; Entry *Fd, *Fs ; Fd = Fublock + fnpiv * fnc_curr ; Fs = Fcblock + fspos ; #pragma ivdep for (j = 0 ; j < fncols ; j++) { Fd [j] = Fs [j * fnr_curr] ; } } /* row of the L2 block: */ if (Work->pivrow_in_front) { Int j ; Entry *Fd, *Fs ; Fd = Flublock + fnpiv ; Fs = Flblock + fspos ; #pragma ivdep for (j = 0 ; j <= fnpiv ; j++) { Fd [j * nb] = Fs [j * fnr_curr] ; } } else { Int j ; Entry *Fd, *Fs ; Fd = Flublock + fnpiv ; Fs = Flblock + fspos ; #pragma ivdep for (j = 0 ; j < fnpiv ; j++) { ASSERT (IS_ZERO (Fs [j * fnr_curr])) ; CLEAR (Fd [j * nb]) ; } Fd [fnpiv * nb] = Fs [fnpiv * fnr_curr] ; } } else { /* ------------------------------------------------------------------ */ /* move Fs => Fd */ /* move Fe => Fs */ /* ------------------------------------------------------------------ */ DEBUG6 (("row case 2\n")) ; /* this is the most common case, by far */ /* row of the contribution block: */ { /* Fd: destination of pivot row on U block */ /* Fs: current position of pivot row in contribution block */ /* Fe: position of last row in contribution block */ Entry *Fd, *Fs, *Fe ; Fd = Fublock + fnpiv * fnc_curr ; Fs = Fcblock + fspos ; Fe = Fcblock + fnrows ; shift_pivot_row (Fd, Fs, Fe, fncols, fnr_curr) ; } /* row of the L2 block: */ if (Work->pivrow_in_front) { /* Fd: destination of pivot row in LU block */ /* Fs: current position of pivot row in L block */ /* Fe: last row in L block */ Int j ; Entry *Fd, *Fs, *Fe ; Fd = Flublock + fnpiv ; Fs = Flblock + fspos ; Fe = Flblock + fnrows ; #pragma ivdep for (j = 0 ; j <= fnpiv ; j++) { Fd [j * nb] = Fs [j * fnr_curr] ; Fs [j * fnr_curr] = Fe [j * fnr_curr] ; } } else { Int j ; Entry *Fd, *Fs, *Fe ; Fd = Flublock + fnpiv ; Fs = Flblock + fspos ; Fe = Flblock + fnrows ; #pragma ivdep for (j = 0 ; j < fnpiv ; j++) { ASSERT (IS_ZERO (Fs [j * fnr_curr])) ; CLEAR (Fd [j * nb]) ; Fs [j * fnr_curr] = Fe [j * fnr_curr] ; } Fd [fnpiv * nb] = Fs [fnpiv * fnr_curr] ; Fs [fnpiv * fnr_curr] = Fe [fnpiv * fnr_curr] ; } /* move row Fe to Fs in the Frows pattern */ row2 = Frows [fnrows] ; Frows [fspos] = row2 ; Frpos [row2] = fspos ; } /* pivot row is no longer in the frontal matrix */ Frpos [pivrow] = EMPTY ; #ifndef NDEBUG DEBUG2 (("\nFrontal matrix after row swap, including all space:\n" "fnr_curr "ID" fnc_curr "ID" nb "ID"\n" "fnrows "ID" fncols "ID" fnpiv "ID"\n", Work->fnr_curr, Work->fnc_curr, Work->nb, Work->fnrows, Work->fncols, Work->fnpiv)) ; DEBUG2 (("\nJust the active part:\n")) ; DEBUG7 (("C block: ")) ; UMF_dump_dense (Fcblock, fnr_curr, fnrows, fncols) ; DEBUG7 (("L block: ")) ; UMF_dump_dense (Flblock, fnr_curr, fnrows, fnpiv+1); DEBUG7 (("U' block: ")) ; UMF_dump_dense (Fublock, fnc_curr, fncols, fnpiv+1) ; DEBUG7 (("LU block: ")) ; UMF_dump_dense (Flublock, nb, fnpiv+1, fnpiv+1) ; #endif /* ---------------------------------------------------------------------- */ /* Frpos [row] >= 0 for each row in pivot column pattern. */ /* offset into pattern is given by: */ /* Frpos [row] == offset - 1 */ /* Frpos [pivrow] is EMPTY */ /* Fcpos [col] >= 0 for each col in pivot row pattern. */ /* Fcpos [col] == (offset - 1) * fnr_curr */ /* Fcpos [pivcol] is EMPTY */ /* Fcols [0..fncols-1] is the pivot row pattern (excl pivot cols) */ /* Frows [0..fnrows-1] is the pivot col pattern (excl pivot rows) */ /* ====================================================================== */ /* === scale pivot column =============================================== */ /* ====================================================================== */ /* pivot column (except for pivot entry itself) */ Fcol = Flblock + fnpiv * fnr_curr ; /* fnpiv-th pivot in frontal matrix located in Flublock (fnpiv, fnpiv) */ pivot_value = Flublock [fnpiv + fnpiv * nb] ; /* this is the kth global pivot */ k = Work->npiv + fnpiv ; DEBUG4 (("Pivot value: ")) ; EDEBUG4 (pivot_value) ; DEBUG4 (("\n")) ; UMF_scale (fnrows, pivot_value, Fcol) ; /* ---------------------------------------------------------------------- */ /* deallocate the pivot row and pivot column tuples */ /* ---------------------------------------------------------------------- */ UMF_mem_free_tail_block (Numeric, Row_tuples [pivrow]) ; UMF_mem_free_tail_block (Numeric, Col_tuples [pivcol]) ; Row_tuples [pivrow] = 0 ; Col_tuples [pivcol] = 0 ; DEBUG5 (("number of pivots prior to this one: "ID"\n", k)) ; ASSERT (NON_PIVOTAL_ROW (pivrow)) ; ASSERT (NON_PIVOTAL_COL (pivcol)) ; /* save row and column inverse permutation */ k1 = ONES_COMPLEMENT (k) ; Rperm [pivrow] = k1 ; /* aliased with Row_degree */ Cperm [pivcol] = k1 ; /* aliased with Col_degree */ ASSERT (!NON_PIVOTAL_ROW (pivrow)) ; ASSERT (!NON_PIVOTAL_COL (pivcol)) ; /* ---------------------------------------------------------------------- */ /* Keep track of the pivot order. This is the kth pivot row and column. */ /* ---------------------------------------------------------------------- */ /* keep track of pivot rows and columns in the LU, L, and U blocks */ ASSERT (fnpiv < MAXNB) ; Work->Pivrow [fnpiv] = pivrow ; Work->Pivcol [fnpiv] = pivcol ; /* ====================================================================== */ /* === one step in the factorization is done ============================ */ /* ====================================================================== */ /* One more step is done, except for pending updates to the U and C blocks * of this frontal matrix. Those are saved up, and applied by * UMF_blas3_update when enough pivots have accumulated. Also, the * LU factors for these pending pivots have not yet been stored. */ Work->fnpiv++ ; #ifndef NDEBUG DEBUG7 (("Current frontal matrix: (after pivcol scale)\n")) ; UMF_dump_current_front (Numeric, Work, TRUE) ; #endif }
// --------------------------------------------------------------------------- // --------------------------------------------------------------------------- // core_error_e core_scan_list_c::update_entry( core_ap_data_c& ap_data ) { bool_t is_match_found( false_t ); const core_mac_address_s bssid( ap_data.bssid() ); core_ssid_s ssid( ap_data.ssid() ); u64_t timestamp( core_am_tools_c::timestamp() ); DEBUG6( "core_scan_list_c::update_entry() - searching for entries with BSSID %02X:%02X:%02X:%02X:%02X:%02X", bssid.addr[0], bssid.addr[1], bssid.addr[2], bssid.addr[3], bssid.addr[4], bssid.addr[5] ); DEBUG1S( "core_scan_list_c::update_entry() - and with SSID ", ssid.length, &ssid.ssid[0] ); core_scan_list_entry_s* iter = scan_list_m.first(); while( iter ) { bool_t is_goto_next_entry( true_t ); if ( iter->ap_data->bssid() == bssid ) { if ( iter->ap_data->ssid() == ssid ) { if ( !is_match_found ) { if ( !iter->tags && iter->ap_data->rcpi() >= ap_data.rcpi() ) { if ( ap_data.frame()->type() == core_frame_dot11_c::core_dot11_type_beacon ) { DEBUG2( "core_scan_list_c::update_entry() - an entry with matching BSSID and SSID (age %u, RCPI %u) already received, ignoring beacon entry", static_cast<u32_t>( timestamp - iter->timestamp ) / SECONDS_FROM_MICROSECONDS, iter->ap_data->rcpi() ); } else { DEBUG2( "core_scan_list_c::update_entry() - an entry with matching BSSID and SSID (age %u, RCPI %u) already received, ignoring probe entry", static_cast<u32_t>( timestamp - iter->timestamp ) / SECONDS_FROM_MICROSECONDS, iter->ap_data->rcpi() ); } is_match_found = true_t; } else { if ( ap_data.frame()->type() == core_frame_dot11_c::core_dot11_type_beacon ) { DEBUG2( "core_scan_list_c::update_entry() - an entry with matching BSSID and SSID (age %u, RCPI %u) found, replacing entry with a beacon entry", static_cast<u32_t>( timestamp - iter->timestamp ) / SECONDS_FROM_MICROSECONDS, iter->ap_data->rcpi() ); } else { DEBUG2( "core_scan_list_c::update_entry() - an entry with matching BSSID and SSID (age %u, RCPI %u) found, replacing entry with a probe entry", static_cast<u32_t>( timestamp - iter->timestamp ) / SECONDS_FROM_MICROSECONDS, iter->ap_data->rcpi() ); } is_match_found = true_t; *(iter->ap_data) = ap_data; iter->timestamp = timestamp; iter->tags = 0; } } else { DEBUG( "core_scan_list_c::update_entry() - an entry with matching BSSID and SSID found (duplicate), removing entry" ); core_scan_list_entry_s* temp = iter; iter = scan_list_m.next(); scan_list_m.remove( temp ); is_goto_next_entry = false_t; } } else if ( iter->ap_data->frame()->type() == core_frame_dot11_c::core_dot11_type_beacon && ap_data.frame()->type() == core_frame_dot11_c::core_dot11_type_beacon ) { /** * If both the new entry and the old entry are beacons with different SSIDs, * it means the SSID has changed and the old entry needs to be replaced or * removed. */ if ( !is_match_found ) { DEBUG( "core_scan_list_c::update_entry() - two beacons with the same BSSID but different SSID found, replacing entry" ); is_match_found = true_t; *(iter->ap_data) = ap_data; iter->timestamp = timestamp; iter->tags = 0; } else { DEBUG( "core_scan_list_c::update_entry() - two beacons with the same BSSID but different SSID found (duplicate), removing entry" ); core_scan_list_entry_s* temp = iter; iter = scan_list_m.next(); scan_list_m.remove( temp ); is_goto_next_entry = false_t; } } #if 0 else { DEBUG( "core_scan_list_c::update_entry() - an entry with matching BSSID found but SSID doesn't match, refreshing entry timestamp" ); iter->timestamp = timestamp; } #endif // 0 } if ( is_goto_next_entry ) { iter = scan_list_m.next(); } } if ( !is_match_found ) { if ( ap_data.frame()->type() == core_frame_dot11_c::core_dot11_type_beacon ) { DEBUG( "core_scan_list_c::update_entry() - no entry matching BSSID and SSID found, adding a new beacon entry" ); } else { DEBUG( "core_scan_list_c::update_entry() - no entry matching BSSID and SSID found, adding a new probe entry" ); } core_scan_list_entry_s* entry = new core_scan_list_entry_s; if ( entry ) { entry->ap_data = core_ap_data_c::instance( ap_data ); entry->timestamp = timestamp; entry->tags = 0; scan_list_m.append( entry ); } } return core_error_ok; }
// --------------------------------------------------------------------------- // --------------------------------------------------------------------------- // core_error_e core_operation_release_c::next_state() { DEBUG( "core_operation_release_c::next_state()" ); switch( operation_state_m ) { case core_state_init: { DEBUG( "core_operation_release_c::next_state() - core_state_init" ); // ensure state is correct if( server_m->get_core_settings().connection_state() == core_connection_state_notconnected ) { return core_error_not_supported; } DEBUG( "core_operation_release_c::next_state() - marking is_disconnecting as true" ); server_m->get_connection_data()->set_disconnecting( true_t ); server_m->cancel_roam_timer(); server_m->cancel_dhcp_timer(); server_m->get_wpx_adaptation_instance().handle_wpx_connection_stop(); #ifdef _DEBUG switch ( reason_m ) { case core_release_reason_external_request: DEBUG( "core_operation_release_c::next_state() - release due to core_release_reason_external_request" ); break; case core_release_reason_max_roam_attempts_exceeded: DEBUG( "core_operation_release_c::next_state() - release due to core_release_reason_max_roam_attempts_exceeded" ); switch ( server_m->get_connection_data()->last_roam_reason() ) { case core_roam_reason_initial_connect: DEBUG( "core_operation_release_c::next_state() - roam was initiated due to core_roam_reason_initial_connect" ); break; case core_roam_reason_bss_lost: DEBUG( "core_operation_release_c::next_state() - roam was initiated due to core_roam_reason_bss_lost" ); break; case core_roam_reason_media_disconnect: DEBUG( "core_operation_release_c::next_state() - roam was initiated due to core_roam_reason_media_disconnect" ); break; case core_roam_reason_signal_strength: DEBUG( "core_operation_release_c::next_state() - roam was initiated due to core_roam_reason_signal_strength" ); break; case core_roam_reason_signal_loss_prediction: DEBUG( "core_operation_release_c::next_state() - roam was initiated due to core_roam_reason_signal_loss_prediction" ); break; case core_roam_reason_failed_reauthentication: DEBUG( "core_operation_release_c::next_state() - roam was initiated due to core_roam_reason_failed_reauthentication" ); break; default: DEBUG( "core_operation_release_c::next_state() - roam was initiated due to an undefined reason" ); ASSERT( false_t ); } switch ( server_m->get_connection_data()->last_roam_failed_reason() ) { case core_roam_failed_reason_timeout: DEBUG( "core_operation_release_c::next_state() - roam failed due to core_roam_failed_reason_timeout" ); break; case core_roam_failed_reason_no_suitable_ap: DEBUG( "core_operation_release_c::next_state() - roam failed due to core_roam_failed_reason_no_suitable_ap" ); break; case core_roam_failed_reason_ap_status_code: DEBUG( "core_operation_release_c::next_state() - roam failed due to core_roam_failed_reason_ap_status_code" ); break; case core_roam_failed_reason_eapol_failure: DEBUG( "core_operation_release_c::next_state() - roam failed due to core_roam_failed_reason_eapol_failure" ); break; case core_roam_failed_reason_other_failure: DEBUG( "core_operation_release_c::next_state() - roam failed due to core_roam_failed_reason_other_failure" ); break; default: DEBUG( "core_operation_release_c::next_state() - roam failed due to an undefined reason" ); ASSERT( false_t ); } break; case core_release_reason_hw_failure: DEBUG( "core_operation_release_c::next_state() - release due to core_release_reason_hw_failure" ); break; case core_release_reason_tkip_mic_failure: DEBUG( "core_operation_release_c::next_state() - release due to core_release_reason_tkip_mic_failure" ); break; case core_release_reason_other: DEBUG( "core_operation_release_c::next_state() - release due to core_release_reason_other" ); break; default: DEBUG( "core_operation_release_c::next_state() - release due to an undefined reason" ); ASSERT( false_t ); } server_m->get_core_settings().roam_metrics().trace_current_roam_metrics(); #endif // _DEBUG /** * EAPOL must notified about the disassociation. */ if ( ( server_m->get_connection_data()->iap_data().is_eap_used() || server_m->get_connection_data()->iap_data().is_wapi_used() ) && server_m->get_connection_data()->current_ap_data() ) { /*const*/ core_mac_address_s bssid = server_m->get_connection_data()->current_ap_data()->bssid(); network_id_c network( &bssid.addr[0], MAC_ADDR_LEN, &server_m->own_mac_addr().addr[0], MAC_ADDR_LEN, server_m->get_eapol_instance().ethernet_type() ); DEBUG6( "core_operation_release_c::next_state() - EAPOL disassociation from BSSID %02X:%02X:%02X:%02X:%02X:%02X", bssid.addr[0], bssid.addr[1], bssid.addr[2], bssid.addr[3], bssid.addr[4], bssid.addr[5] ); DEBUG( "core_operation_release_c::next_state() - marking is_eapol_disconnecting as true" ); server_m->get_connection_data()->set_eapol_disconnecting( true ); server_m->get_eapol_instance().disassociation( &network ); operation_state_m = core_state_eapol_disassociated; return core_error_request_pending; } return goto_state( core_state_eapol_disassociated ); } case core_state_eapol_disassociated: { DEBUG( "core_operation_release_c::next_state() - core_state_eapol_disassociated" ); // disable user data drivers_m->disable_user_data( request_id_m ); operation_state_m = core_state_disable_user_data; break; } case core_state_disable_user_data: { DEBUG( "core_operation_release_c::next_state() - core_state_disable_user_data" ); drivers_m->set_tx_power_level( request_id_m, server_m->get_device_settings().tx_power_level ); operation_state_m = core_state_tx_power_level; break; } case core_state_tx_power_level: { DEBUG( "core_operation_release_c::next_state() - core_state_tx_power_level" ); u32_t tx_level = server_m->get_device_settings().tx_power_level; if ( server_m->get_connection_data()->last_tx_level() != tx_level ) { DEBUG( "core_operation_release_c::next_state() - TX level has changed, notifying change" ); adaptation_m->notify( core_notification_tx_power_level_changed, sizeof( tx_level ), reinterpret_cast<u8_t*>( &tx_level ) ); server_m->get_connection_data()->set_last_tx_level( tx_level ); } drivers_m->disconnect( request_id_m ); operation_state_m = core_state_disconnect; break; } case core_state_disconnect: { DEBUG( "core_operation_release_c::next_state() - core_state_disconnect" ); // notify adaptation core_connection_state_e state = core_connection_state_notconnected; server_m->get_core_settings().set_connection_state( state ); if ( server_m->get_connection_data()->last_connection_state() != state ) { u8_t buf[5]; buf[0] = static_cast<u8_t>( state ); buf[1] = static_cast<u8_t>( reason_m ); buf[2] = 0; buf[3] = 0; if ( reason_m == core_release_reason_max_roam_attempts_exceeded ) { buf[2] = static_cast<u8_t>( server_m->get_connection_data()->last_roam_reason() ); buf[3] = static_cast<u8_t>( server_m->get_connection_data()->last_roam_failed_reason() ); } adaptation_m->notify( core_notification_connection_state_changed, sizeof( buf ), buf ); server_m->get_connection_data()->set_last_connection_state( state ); } // destroy connection data server_m->clear_connection_data(); // Cancel any operations that depend on an active connection. server_m->cancel_operations_with_flags( core_operation_base_c::core_base_flag_connection_needed ); return core_error_ok; } default: { ASSERT( false_t ); } } return core_error_request_pending; }
void MisCheck(char plr, char mpad) { int tomflag = 0; // toms checking flag int val, safety, save, PROBLEM, i, lc, durxx; struct XFails Now; unsigned char gork = 0; lc = 0; /* XXX check uninitialized */ STEPnum = STEP; FINAL = STEP = MFlag = 0; // Clear Everything Unm = MANNED[0] + MANNED[1]; Dock_Skip = 0; // used for mission branching MPad = mpad; SCRUBS = noDock = InSpace = 0; if (!AI[plr] && !fullscreenMissionPlayback) { //FadeOut(1,pal,100,128,1); if (plr == 1) { fill_rectangle(189, 173, 249, 196, 55); for (i = 190; i < 250; i += 2) { display::graphics.legacyScreen()->setPixel(i, 178, 61); display::graphics.legacyScreen()->setPixel(i, 184, 61); display::graphics.legacyScreen()->setPixel(i, 190, 61); } lc = 191; } else if (plr == 0) { fill_rectangle(73, 173, 133, 196, 55); for (i = 73; i < 133; i += 2) { display::graphics.legacyScreen()->setPixel(i, 178, 61); display::graphics.legacyScreen()->setPixel(i, 184, 61); display::graphics.legacyScreen()->setPixel(i, 190, 61); } lc = 76; } } // END if (!AI[plr]) if (!AI[plr] && !fullscreenMissionPlayback) { Tick(2); } Mev[0].trace = 0; death = 0; durxx = durx = -1; if (Data->P[plr].Mission[mpad].Duration > 0) { durxx = Data->P[plr].Mission[mpad].Duration - 1; Data->P[plr].Mission[mpad].Duration = 0; } if (JOINT == 1) { durxx = MAX(durxx, Data->P[plr].Mission[mpad + 1].Duration - 1); Data->P[plr].Mission[mpad + 1].Duration = 0; } do { if (STEP > 30 || STEP < 0) { delay(20); } if (Dock_Skip == 1) { if (Mev[Mev[STEP].trace].loc == 8) { Mev[STEP].trace++; // skip over docking. } } if (Mev[STEP].loc == 16 && Mis.PCat[4] == 22) { FirstManOnMoon(plr, 0, Mis.Index); } // Duration Hack Part 1 of 3 (during the Duration stuff) if ((Mev[STEP].loc == 27 || Mev[STEP].loc == 28) && durx > 0) { if (Mev[STEP].StepInfo != 1) { Data->P[plr].Mission[MPad + Mev[STEP].pad].Duration = 1; //Original code would also return 1 durx = -1; // end durations } else { Data->P[plr].Mission[MPad + Mev[STEP].pad].Duration++; durx--; if ((Data->Def.Lev1 == 0 && plr == 0) || (Data->Def.Lev2 == 0 && plr == 1)) { Mev[STEP].dice = MisRandom(); } else { Mev[STEP].dice = brandom(100) + 1; } Mev[STEP].rnum = brandom(10000); // reroll failure type Mev[STEP].trace = STEP; } } if (Mev[STEP].Name[0] == 'A' || Mev[STEP].StepInfo == 9 || Mev[STEP].StepInfo == 19) { STEP = Mev[STEP].trace; } else { if (Mev[STEP].trace != 0) { STEP = Mev[STEP].trace; } else { Mev[STEP].trace = STEP + 1; STEP++; } } // Duration Hack Part 2 of 3 (set up durx for duration use) if ((Mev[STEP].loc == 27 || Mev[STEP].loc == 28) && durx == -1) { durx = durxx - 1; Data->P[plr].Mission[MPad + Mev[STEP].pad].Duration = 2; } if (Mev[STEP].Name[0] == 'A') { display::graphics.setForegroundColor(11); if (!AI[plr] && !fullscreenMissionPlayback) { if (plr == 0) { x = 5; y = 112; fill_rectangle(2, 107, 140, 115, 3); } else { x = 82, y = 8; fill_rectangle(78, 2, 241, 10, 3); } draw_string(x, y, "COUNTDOWN"); if (plr == 0) { fill_rectangle(188, 107, 294, 113, 3); display::graphics.setForegroundColor(1); draw_string(190, 112, (Mev[STEP].pad == 0) ? "PRIMARY LAUNCH" : "SECOND LAUNCH"); } else { fill_rectangle(244, 56, 314, 62, 3); display::graphics.setForegroundColor(1); draw_string(246, 61, (Mev[STEP].pad == 0) ? "PRIMARY PAD" : "SECOND PAD"); } } memset(Name, 0x00, sizeof Name); strcpy(Name, Mev[STEP].Name); Name[0] = '#'; // Launch Code PlaySequence(plr, STEP, Name, 0); // Special Case #47236 }; // Necessary to keep code from crashing on bogus mission step while (Mev[STEP].E == NULL) { STEP++; } // Draw Mission Step Name if (!AI[plr] && !fullscreenMissionPlayback) { if (!(fEarly && STEP != 0)) { if (plr == 0) { x = 5; y = 112; fill_rectangle(2, 107, 140, 115, 3); } else { x = 82, y = 8; fill_rectangle(78, 2, 241, 10, 3); } display::graphics.setForegroundColor(11); MisStep(x, y, Mev[STEP].loc); if (plr == 0) { fill_rectangle(188, 107, 294, 113, 3); display::graphics.setForegroundColor(1); draw_string(190, 112, (Mev[STEP].pad == 0) ? "PRIMARY LAUNCH" : "SECOND LAUNCH"); } else { fill_rectangle(244, 56, 314, 62, 3); display::graphics.setForegroundColor(1); draw_string(246, 61, (Mev[STEP].pad == 0) ? "PRIMARY PAD" : "SECOND PAD"); } } } // SAFETY FACTOR STUFF safety = Mev[STEP].E->MisSaf; if ((Mev[STEP].Name[0] == 'A') && MH[Mev[STEP].pad][7] != NULL) { // boosters involved safety = RocketBoosterSafety(safety, MH[Mev[STEP].pad][7]->Safety); } // Duration Hack Part 3 of 3 if (Mev[STEP].loc == 28 || Mev[STEP].loc == 27) { safety = Mev[STEP].E->MisSaf; // needs to be for both if (InSpace == 2) { safety = (MH[0][0]->MisSaf + MH[1][0]->MisSaf) / 2; //joints } } if (strncmp(Mev[STEP].E->Name, "DO", 2) == 0) { if (Mev[STEP].loc == 1 || Mev[STEP].loc == 2) { safety = Mev[STEP].E->MSF; } } val = Mev[STEP].dice; safety += Mev[STEP].asf; if (safety >= 100) { safety = 99; } save = (Mev[STEP].E->SaveCard == 1) ? 1 : 0; PROBLEM = val > safety; if (!AI[plr] && options.want_cheats) { PROBLEM = 0; } DEBUG6("step %c:%s safety %d rolled %d%s", Mev[STEP].Name[0], S_Name[Mev[STEP].loc], safety, val, PROBLEM ? " problem" : (options.want_cheats ? " cheating" : "")); if (!AI[plr] && !fullscreenMissionPlayback) if (!(fEarly && STEP != 0)) { lc = MCGraph(plr, lc, MAX(0, safety), MAX(0, val), PROBLEM); // Graph Chart } if (PROBLEM && save == 1) { // Failure Saved Mev[STEP].E->SaveCard--; // Deduct SCard PROBLEM = 0; // Fix problem } // Fix wrong anim thing for the Jt Durations if (Mev[STEP].loc == 28 || Mev[STEP].loc == 27) { strcpy(Mev[STEP].Name, (plr == 0) ? "_BUSC0\0" : "_BSVC0"); Mev[STEP].Name[5] = Mev[STEP].E->ID[1]; } if (PROBLEM == 1) { //Step Problem // for the unmanned mission if (MANNED[Mev[STEP].pad] == 0 && MANNED[other(Mev[STEP].pad)] == 0) { Mev[STEP].rnum = (-1) * (brandom(5) + 1); } // Unmanned also if (MANNED[Mev[STEP].pad] == 0 && noDock == 0) { Mev[STEP].rnum = (-1) * (brandom(5) + 1); } memset(&Now, 0x00, sizeof Now); //***************TC Special little HMOON EVA FAILURE FIX tomflag = 0; if (Mev[STEP].Name[0] == 'H' && Mev[STEP].Name[1] == 'M') { gork = Data->P[plr].Mission[mpad].Prog; if (gork == 2) { strcpy(Mev[STEP].Name, (plr == 0) ? "HUM3C1" : "HSM3C1"); } else if (gork == 3) { strcpy(Mev[STEP].Name, (plr == 0) ? "HUM3C2" : "HSM3C2"); } else { strcpy(Mev[STEP].Name, (plr == 0) ? "HUM3C3" : "HSM3C3"); } tomflag = 1; }; //:::::: Failure docking klugge if (Mev[STEP].Name[0] == 'I') { gork = Data->P[plr].Mission[mpad].Prog; if (gork == 2) { strcpy(Mev[STEP].Name, (plr == 0) ? "IUM4C1" : "ISM4C1"); } else if (gork == 3) { strcpy(Mev[STEP].Name, (plr == 0) ? "IUM4C2" : "ISM4C2"); } else { strcpy(Mev[STEP].Name, (plr == 0) ? "IUM4C3" : "ISM4C3"); } }; // *********** TOM's FAIL HMOON KLUDGE // if HMOON FAILURE if (tomflag) { GetFailStat(&Now, Mev[STEP].FName, 7595); } else { DEBUG3("Failing !tomflag - calling GetFailStat(&Now, Mev[STEP].FName %s, MEV[STEP].rnum %d))", Mev[STEP].FName, Mev[STEP].rnum); GetFailStat(&Now, Mev[STEP].FName, Mev[STEP].rnum); // all others } memset(Name, 0x00, sizeof Name); memcpy(Name, Mev[STEP].Name, strlen(Mev[STEP].Name)); // copy orig failure Name[strlen(Name)] = 0x30 + (Now.fail / 10); Name[strlen(Name)] = 0x30 + Now.fail % 10; Name[strlen(Name)] = 0x00; //:::::: STEP FAILURE ::::::::: //::::::::::::::::::::::::::::: PlaySequence(plr, STEP, Name, 1); if (!AI[plr]) { Tick(2); //reset dials } FailEval(plr, Now.code, Now.text, Now.val, Now.xtra); } else { // Step Success if (Mev[STEP].loc == 28 || Mev[STEP].loc == 27) { strcpy(Mev[STEP].Name, (plr == 0) ? "bUC0" : "bSC0"); Mev[STEP].Name[5] = Mev[STEP].E->ID[1]; } if (strncmp(Mev[STEP].E->Name, "DO", 2) == 0) { if (Mev[STEP].loc == 2) { Data->P[plr].DockingModuleInOrbit = 2; } } //:::::::::::::::::::::::::::::::::: //::: SUCCESS: Docking klugge :::::: //:::::::::::::::::::::::::::::::::: if (Mev[STEP].Name[0] == 'I') { gork = Data->P[plr].Mission[mpad].Prog; if (gork == 2) { strcpy(Mev[STEP].Name, (plr == 0) ? "IUM4C1" : "ISM4C1"); } else if (gork == 3) { strcpy(Mev[STEP].Name, (plr == 0) ? "IUM4C2" : "ISM4C2"); } else { strcpy(Mev[STEP].Name, (plr == 0) ? "IUM4C3" : "ISM4C3"); } }; if (Mev[STEP].Name[0] == 'e' && Data->P[plr].Mission[mpad].MissionCode == Mission_LunarFlyby) { strcpy(Mev[STEP].Name, (plr == 0) ? "VUP1" : "VSP1"); } //:::::: STEP SUCCESS ::::::::: //::::::::::::::::::::::::::::: // FemaleAstronautsAllowed step klugge // third parameter (0 -> MALE) (2 -> FEMALE) //::::::::::::::::::::::::::::: gork = ((MA[0][0].A != NULL && MA[0][0].A->Sex && EVA[0] == 0) || (MA[0][1].A != NULL && MA[0][1].A->Sex && EVA[0] == 1) || (MA[0][2].A != NULL && MA[0][2].A->Sex && EVA[0] == 2) || (MA[0][3].A != NULL && MA[0][3].A->Sex && EVA[0] == 3) || (MA[1][0].A != NULL && MA[1][0].A->Sex && EVA[1] == 0) || (MA[1][1].A != NULL && MA[1][1].A->Sex && EVA[1] == 1) || (MA[1][2].A != NULL && MA[1][2].A->Sex && EVA[1] == 2) || (MA[1][3].A != NULL && MA[1][3].A->Sex && EVA[1] == 3)); //if (!((mcc==9 || mcc==11) && (Mev[STEP].Name[0]=='W'))) PlaySequence(plr, STEP, Mev[STEP].Name, (gork == 1) ? 2 : 0); // Play Animations if (Mev[STEP].sgoto == 100) { Mev[STEP].trace = 0x7F; } else if (Mev[STEP].sgoto != 0) { Mev[STEP].trace = Mev[STEP].sgoto; } else { Mev[STEP].trace = STEP + 1; } if (!(strncmp(Mev[STEP].E->Name, "DO", 2) == 0 && Mev[STEP].loc == 0x02)) { Mev[STEP].E->MisSucc++; // set for all but docking power on } Mev[STEP].StepInfo = 1; // Bottom of success statement } if (Mev[STEP].loc == 0x7f || Mev[STEP].sgoto == 100) { // force mission end Mev[STEP].trace = 0x7f; } if ((mcc == 10 || mcc == 12 || mcc == 13) && STEP == 2) { Mev[STEP].trace = 0x7f; } if (STEP > 30 || STEP < 0) { delay(20); } if (Mev[STEP].Prest != 0) { pAry[pCnt++] = STEP; } if (Mev[STEP].sgoto == Mev[STEP].fgoto && Mev[STEP].trace != 0x7f) { Mev[STEP].trace = Mev[STEP].sgoto; } if (Mev[STEP].loc == 8 && Mev[STEP].StepInfo == 1) { noDock = 1; } if (Mev[STEP].loc == 0 && MANNED[Mev[STEP].pad] > 0) { InSpace++; } if (Mev[STEP].loc == 4 && MANNED[Mev[STEP].pad] > 0) { InSpace--; } // these two lines fix a problem with Lab Missions failing on launch and // ending the mission. // Yet another in the ongoing series of special cases. // if (Mev[STEP].trace == 0x7f && STEP == 3) { switch (Mis.Index) { case 19: case 22: case 23: case 30: case 32: case 35: case 36: case 37: InSpace = 1; Mev[STEP].trace = Mev[STEP].dgoto; default: break; } } // if (Mev[STEP].trace==0x7f && InSpace>0) Mev[STEP].trace=STEP+1; } while (Mev[STEP].trace != 0x7f); // End mission //end do if (!AI[plr] && death == 0) { delay(1000); } if ((MA[0][0].A != NULL && MA[0][0].A->Status == AST_ST_DEAD) || (MA[0][1].A != NULL && MA[0][1].A->Status == AST_ST_DEAD) || (MA[0][2].A != NULL && MA[0][2].A->Status == AST_ST_DEAD) || (MA[0][3].A != NULL && MA[0][3].A->Status == AST_ST_DEAD) || (MA[1][0].A != NULL && MA[1][0].A->Status == AST_ST_DEAD) || (MA[1][1].A != NULL && MA[1][1].A->Status == AST_ST_DEAD) || (MA[1][2].A != NULL && MA[1][2].A->Status == AST_ST_DEAD) || (MA[1][3].A != NULL && MA[1][3].A->Status == AST_ST_DEAD)) { // Mission Death if (!AI[plr]) { if (!fullscreenMissionPlayback) { display::AutoPal p(display::graphics.legacyScreen()); memset(&p.pal[64 * 3], 0x00, 64 * 3); //Specs: 0x08 if (plr == 0) { fill_rectangle(2, 107, 140, 115, 3); } else { fill_rectangle(78, 2, 241, 10, 3); } if (plr == 0) { fill_rectangle(188, 107, 294, 113, 3); } else { fill_rectangle(244, 56, 314, 62, 3); } } PlaySequence(plr, STEP, (plr == 0) ? "UFUN" : "SFUN", 0); } if (!AI[plr]) { delay(1000); } death = 1; } else { death = 0; }; return; }
GLOBAL Int UMF_row_search ( NumericType *Numeric, WorkType *Work, SymbolicType *Symbolic, Int cdeg0, /* length of column in Front */ Int cdeg1, /* length of column outside Front */ const Int Pattern [ ], /* pattern of column, Pattern [0..cdeg1 -1] */ const Int Pos [ ], /* Pos [Pattern [0..cdeg1 -1]] = 0..cdeg1 -1 */ Int pivrow [2], /* pivrow [IN] and pivrow [OUT] */ Int rdeg [2], /* rdeg [IN] and rdeg [OUT] */ Int W_i [ ], /* pattern of pivrow [IN], */ /* either Fcols or Woi */ Int W_o [ ], /* pattern of pivrow [OUT], */ /* either Wio or Woo */ Int prior_pivrow [2], /* the two other rows just scanned, if any */ const Entry Wxy [ ], /* numerical values Wxy [0..cdeg1-1], either Wx or Wy */ Int pivcol, /* the candidate column being searched */ Int freebie [ ] ) { /* ---------------------------------------------------------------------- */ /* local variables */ /* ---------------------------------------------------------------------- */ double maxval, toler, toler2, value, pivot [2] ; Int i, row, deg, col, *Frpos, fnrows, *E, j, ncols, *Cols, *Rows, e, f, Wrpflag, *Fcpos, fncols, tpi, max_rdeg, nans_in_col, was_offdiag, diag_row, prefer_diagonal, *Wrp, found, *Diagonal_map ; Tuple *tp, *tpend, *tp1, *tp2 ; Unit *Memory, *p ; Element *ep ; Int *Row_tuples, *Row_degree, *Row_tlen ; #ifndef NDEBUG Int *Col_degree ; DEBUG2 (("Row_search:\n")) ; for (i = 0 ; i < cdeg1 ; i++) { row = Pattern [i] ; DEBUG4 ((" row: "ID"\n", row)) ; ASSERT (row >= 0 && row < Numeric->n_row) ; ASSERT (i == Pos [row]) ; } /* If row is not in Pattern [0..cdeg1-1], then Pos [row] == EMPTY */ if (UMF_debug > 0 || Numeric->n_row < 1000) { Int cnt = cdeg1 ; DEBUG4 (("Scan all rows:\n")) ; for (row = 0 ; row < Numeric->n_row ; row++) { if (Pos [row] < 0) { cnt++ ; } else { DEBUG4 ((" row: "ID" pos "ID"\n", row, Pos [row])) ; } } ASSERT (cnt == Numeric->n_row) ; } Col_degree = Numeric->Cperm ; /* for NON_PIVOTAL_COL macro only */ ASSERT (pivcol >= 0 && pivcol < Work->n_col) ; ASSERT (NON_PIVOTAL_COL (pivcol)) ; #endif pivot [IN] = 0. ; pivot [OUT] = 0. ; /* ---------------------------------------------------------------------- */ /* get parameters */ /* ---------------------------------------------------------------------- */ Row_degree = Numeric->Rperm ; Row_tuples = Numeric->Uip ; Row_tlen = Numeric->Uilen ; Wrp = Work->Wrp ; Frpos = Work->Frpos ; E = Work->E ; Memory = Numeric->Memory ; fnrows = Work->fnrows ; prefer_diagonal = Symbolic->prefer_diagonal ; Diagonal_map = Work->Diagonal_map ; if (Diagonal_map) { diag_row = Diagonal_map [pivcol] ; was_offdiag = diag_row < 0 ; if (was_offdiag) { /* the "diagonal" entry in this column was permuted here by an * earlier pivot choice. The tighter off-diagonal tolerance will * be used instead of the symmetric tolerance. */ diag_row = FLIP (diag_row) ; } ASSERT (diag_row >= 0 && diag_row < Numeric->n_row) ; } else { diag_row = EMPTY ; /* unused */ was_offdiag = EMPTY ; /* unused */ } /* pivot row degree cannot exceed max_rdeg */ max_rdeg = Work->fncols_max ; /* ---------------------------------------------------------------------- */ /* scan pivot column for candidate rows */ /* ---------------------------------------------------------------------- */ maxval = 0.0 ; nans_in_col = FALSE ; for (i = 0 ; i < cdeg1 ; i++) { APPROX_ABS (value, Wxy [i]) ; if (SCALAR_IS_NAN (value)) { nans_in_col = TRUE ; maxval = value ; break ; } /* This test can now ignore the NaN case: */ maxval = MAX (maxval, value) ; } /* if maxval is zero, the matrix is numerically singular */ toler = Numeric->relpt * maxval ; toler2 = Numeric->relpt2 * maxval ; toler2 = was_offdiag ? toler : toler2 ; DEBUG5 (("Row_search begins [ maxval %g toler %g %g\n", maxval, toler, toler2)) ; if (SCALAR_IS_NAN (toler) || SCALAR_IS_NAN (toler2)) { nans_in_col = TRUE ; } if (!nans_in_col) { /* look for the diagonal entry, if it exists */ found = FALSE ; ASSERT (!SCALAR_IS_NAN (toler)) ; if (prefer_diagonal) { ASSERT (diag_row != EMPTY) ; i = Pos [diag_row] ; if (i >= 0) { double a ; ASSERT (i < cdeg1) ; ASSERT (diag_row == Pattern [i]) ; APPROX_ABS (a, Wxy [i]) ; ASSERT (!SCALAR_IS_NAN (a)) ; ASSERT (!SCALAR_IS_NAN (toler2)) ; if (SCALAR_IS_NONZERO (a) && a >= toler2) { /* found it! */ DEBUG3 (("Symmetric pivot: "ID" "ID"\n", pivcol, diag_row)); found = TRUE ; if (Frpos [diag_row] >= 0 && Frpos [diag_row] < fnrows) { pivrow [IN] = diag_row ; pivrow [OUT] = EMPTY ; } else { pivrow [IN] = EMPTY ; pivrow [OUT] = diag_row ; } } } } /* either no diagonal found, or we didn't look for it */ if (!found) { if (cdeg0 > 0) { /* this is a column in the front */ for (i = 0 ; i < cdeg0 ; i++) { double a ; APPROX_ABS (a, Wxy [i]) ; ASSERT (!SCALAR_IS_NAN (a)) ; ASSERT (!SCALAR_IS_NAN (toler)) ; if (SCALAR_IS_NONZERO (a) && a >= toler) { row = Pattern [i] ; deg = Row_degree [row] ; #ifndef NDEBUG DEBUG6 ((ID" candidate row "ID" deg "ID" absval %g\n", i, row, deg, a)) ; UMF_dump_rowcol (0, Numeric, Work, row, TRUE) ; #endif ASSERT (Frpos [row] >= 0 && Frpos [row] < fnrows) ; ASSERT (Frpos [row] == i) ; /* row is in the current front */ DEBUG4 ((" in front\n")) ; if (deg < rdeg [IN] /* break ties by picking the largest entry: */ || (deg == rdeg [IN] && a > pivot [IN]) /* break ties by picking the diagonal entry: */ /* || (deg == rdeg [IN] && row == diag_row) */ ) { /* best row in front, so far */ pivrow [IN] = row ; rdeg [IN] = deg ; pivot [IN] = a ; } } } for ( ; i < cdeg1 ; i++) { double a ; APPROX_ABS (a, Wxy [i]) ; ASSERT (!SCALAR_IS_NAN (a)) ; ASSERT (!SCALAR_IS_NAN (toler)) ; if (SCALAR_IS_NONZERO (a) && a >= toler) { row = Pattern [i] ; deg = Row_degree [row] ; #ifndef NDEBUG DEBUG6 ((ID" candidate row "ID" deg "ID" absval %g\n", i, row, deg, a)) ; UMF_dump_rowcol (0, Numeric, Work, row, TRUE) ; #endif ASSERT (Frpos [row] == i) ; /* row is not in the current front */ DEBUG4 ((" NOT in front\n")) ; if (deg < rdeg [OUT] /* break ties by picking the largest entry: */ || (deg == rdeg [OUT] && a > pivot [OUT]) /* break ties by picking the diagonal entry: */ /* || (deg == rdeg [OUT] && row == diag_row) */ ) { /* best row not in front, so far */ pivrow [OUT] = row ; rdeg [OUT] = deg ; pivot [OUT] = a ; } } } } else { /* this column is not in the front */ for (i = 0 ; i < cdeg1 ; i++) { double a ; APPROX_ABS (a, Wxy [i]) ; ASSERT (!SCALAR_IS_NAN (a)) ; ASSERT (!SCALAR_IS_NAN (toler)) ; if (SCALAR_IS_NONZERO (a) && a >= toler) { row = Pattern [i] ; deg = Row_degree [row] ; #ifndef NDEBUG DEBUG6 ((ID" candidate row "ID" deg "ID" absval %g\n", i, row, deg, a)) ; UMF_dump_rowcol (0, Numeric, Work, row, TRUE) ; #endif if (Frpos [row] >= 0 && Frpos [row] < fnrows) { /* row is in the current front */ DEBUG4 ((" in front\n")) ; if (deg < rdeg [IN] /* break ties by picking the largest entry: */ || (deg == rdeg [IN] && a > pivot [IN]) /* break ties by picking the diagonal entry: */ /* || (deg == rdeg [IN] && row == diag_row) */ ) { /* best row in front, so far */ pivrow [IN] = row ; rdeg [IN] = deg ; pivot [IN] = a ; } } else { /* row is not in the current front */ DEBUG4 ((" NOT in front\n")) ; if (deg < rdeg [OUT] /* break ties by picking the largest entry: */ || (deg == rdeg[OUT] && a > pivot [OUT]) /* break ties by picking the diagonal entry: */ /* || (deg == rdeg[OUT] && row == diag_row) */ ) { /* best row not in front, so far */ pivrow [OUT] = row ; rdeg [OUT] = deg ; pivot [OUT] = a ; } } } } } } } /* ---------------------------------------------------------------------- */ /* NaN handling */ /* ---------------------------------------------------------------------- */ /* if cdeg1 > 0 then we must have found a pivot row ... unless NaN's */ /* exist. Try with no numerical tests if no pivot found. */ if (cdeg1 > 0 && pivrow [IN] == EMPTY && pivrow [OUT] == EMPTY) { /* cleanup for the NaN case */ DEBUG0 (("Found a NaN in pivot column!\n")) ; /* grab the first entry in the pivot column, ignoring degree, */ /* numerical stability, and symmetric preference */ row = Pattern [0] ; deg = Row_degree [row] ; if (Frpos [row] >= 0 && Frpos [row] < fnrows) { /* row is in the current front */ DEBUG4 ((" in front\n")) ; pivrow [IN] = row ; rdeg [IN] = deg ; } else { /* row is not in the current front */ DEBUG4 ((" NOT in front\n")) ; pivrow [OUT] = row ; rdeg [OUT] = deg ; } /* We are now guaranteed to have a pivot, no matter how broken */ /* (non-IEEE compliant) the underlying numerical operators are. */ /* This is particularly a problem for Microsoft compilers (they do */ /* not handle NaN's properly). Now try to find a sparser pivot, if */ /* possible. */ for (i = 1 ; i < cdeg1 ; i++) { row = Pattern [i] ; deg = Row_degree [row] ; if (Frpos [row] >= 0 && Frpos [row] < fnrows) { /* row is in the current front */ DEBUG4 ((" in front\n")) ; if (deg < rdeg [IN] || (deg == rdeg [IN] && row == diag_row)) { /* best row in front, so far */ pivrow [IN] = row ; rdeg [IN] = deg ; } } else { /* row is not in the current front */ DEBUG4 ((" NOT in front\n")) ; if (deg < rdeg [OUT] || (deg == rdeg [OUT] && row == diag_row)) { /* best row not in front, so far */ pivrow [OUT] = row ; rdeg [OUT] = deg ; } } } } /* We found a pivot if there are entries (even zero ones) in pivot col */ ASSERT (IMPLIES (cdeg1 > 0, pivrow[IN] != EMPTY || pivrow[OUT] != EMPTY)) ; /* If there are no entries in the pivot column, then no pivot is found */ ASSERT (IMPLIES (cdeg1 == 0, pivrow[IN] == EMPTY && pivrow[OUT] == EMPTY)) ; /* ---------------------------------------------------------------------- */ /* check for singular matrix */ /* ---------------------------------------------------------------------- */ if (cdeg1 == 0) { if (fnrows > 0) { /* Get the pivrow [OUT][IN] from the current front. The frontal matrix looks like this: pivcol[OUT] | v x x x x 0 <- so grab this row as the pivrow [OUT][IN]. x x x x 0 x x x x 0 0 0 0 0 0 The current frontal matrix has some rows in it. The degree of the pivcol[OUT] is zero. The column is empty, and the current front does not contribute to it. */ pivrow [IN] = Work->Frows [0] ; DEBUGm4 (("Got zero pivrow[OUT][IN] "ID" from current front\n", pivrow [IN])) ; } else { /* Get a pivot row from the row-merge tree, use as pivrow [OUT][OUT]. pivrow [IN] remains EMPTY. This can only happen if the current front is 0-by-0. */ Int *Front_leftmostdesc, *Front_1strow, *Front_new1strow, row1, row2, fleftmost, nfr, n_row, frontid ; ASSERT (Work->fncols == 0) ; Front_leftmostdesc = Symbolic->Front_leftmostdesc ; Front_1strow = Symbolic->Front_1strow ; Front_new1strow = Work->Front_new1strow ; nfr = Symbolic->nfr ; n_row = Numeric->n_row ; frontid = Work->frontid ; DEBUGm4 (("Note: pivcol: "ID" is empty front "ID"\n", pivcol, frontid)) ; #ifndef NDEBUG DEBUG1 (("Calling dump rowmerge\n")) ; UMF_dump_rowmerge (Numeric, Symbolic, Work) ; #endif /* Row-merge set is the non-pivotal rows in the range */ /* Front_new1strow [Front_leftmostdesc [frontid]] to */ /* Front_1strow [frontid+1] - 1. */ /* If this is empty, then use the empty rows, in the range */ /* Front_new1strow [nfr] to n_row-1. */ /* If this too is empty, then pivrow [OUT] will be empty. */ /* In both cases, update Front_new1strow [...]. */ fleftmost = Front_leftmostdesc [frontid] ; row1 = Front_new1strow [fleftmost] ; row2 = Front_1strow [frontid+1] - 1 ; DEBUG1 (("Leftmost: "ID" Rows ["ID" to "ID"] srch ["ID" to "ID"]\n", fleftmost, Front_1strow [frontid], row2, row1, row2)) ; /* look in the range row1 ... row2 */ for (row = row1 ; row <= row2 ; row++) { DEBUG3 ((" Row: "ID"\n", row)) ; if (NON_PIVOTAL_ROW (row)) { /* found it */ DEBUG3 ((" Row: "ID" found\n", row)) ; ASSERT (Frpos [row] == EMPTY) ; pivrow [OUT] = row ; DEBUGm4 (("got row merge pivrow %d\n", pivrow [OUT])) ; break ; } } Front_new1strow [fleftmost] = row ; if (pivrow [OUT] == EMPTY) { /* not found, look in empty row set in "dummy" front */ row1 = Front_new1strow [nfr] ; row2 = n_row-1 ; DEBUG3 (("Empty: "ID" Rows ["ID" to "ID"] srch["ID" to "ID"]\n", nfr, Front_1strow [nfr], row2, row1, row2)) ; /* look in the range row1 ... row2 */ for (row = row1 ; row <= row2 ; row++) { DEBUG3 ((" Empty Row: "ID"\n", row)) ; if (NON_PIVOTAL_ROW (row)) { /* found it */ DEBUG3 ((" Empty Row: "ID" found\n", row)) ; ASSERT (Frpos [row] == EMPTY) ; pivrow [OUT] = row ; DEBUGm4 (("got dummy row pivrow %d\n", pivrow [OUT])) ; break ; } } Front_new1strow [nfr] = row ; } if (pivrow [OUT] == EMPTY) { /* Row-merge set is empty. We can just discard */ /* the candidate pivot column. */ DEBUG0 (("Note: row-merge set empty\n")) ; DEBUGm4 (("got no pivrow \n")) ; return (UMFPACK_WARNING_singular_matrix) ; } } } /* ---------------------------------------------------------------------- */ /* construct the candidate row in the front, if any */ /* ---------------------------------------------------------------------- */ #ifndef NDEBUG /* check Wrp */ ASSERT (Work->Wrpflag > 0) ; if (UMF_debug > 0 || Work->n_col < 1000) { for (i = 0 ; i < Work->n_col ; i++) { ASSERT (Wrp [i] < Work->Wrpflag) ; } } #endif #ifndef NDEBUG DEBUG4 (("pivrow [IN]: "ID"\n", pivrow [IN])) ; UMF_dump_rowcol (0, Numeric, Work, pivrow [IN], TRUE) ; #endif if (pivrow [IN] != EMPTY) { /* the row merge candidate row is not pivrow [IN] */ freebie [IN] = (pivrow [IN] == prior_pivrow [IN]) && (cdeg1 > 0) ; ASSERT (cdeg1 >= 0) ; if (!freebie [IN]) { /* include current front in the degree of this row */ Fcpos = Work->Fcpos ; fncols = Work->fncols ; Wrpflag = Work->Wrpflag ; /* -------------------------------------------------------------- */ /* construct the pattern of the IN row */ /* -------------------------------------------------------------- */ #ifndef NDEBUG /* check Fcols */ DEBUG5 (("ROW ASSEMBLE: rdeg "ID"\nREDUCE ROW "ID"\n", fncols, pivrow [IN])) ; for (j = 0 ; j < fncols ; j++) { col = Work->Fcols [j] ; ASSERT (col >= 0 && col < Work->n_col) ; ASSERT (Fcpos [col] >= 0) ; } if (UMF_debug > 0 || Work->n_col < 1000) { Int cnt = fncols ; for (col = 0 ; col < Work->n_col ; col++) { if (Fcpos [col] < 0) cnt++ ; } ASSERT (cnt == Work->n_col) ; } #endif rdeg [IN] = fncols ; ASSERT (pivrow [IN] >= 0 && pivrow [IN] < Work->n_row) ; ASSERT (NON_PIVOTAL_ROW (pivrow [IN])) ; /* add the pivot column itself */ ASSERT (Wrp [pivcol] != Wrpflag) ; if (Fcpos [pivcol] < 0) { DEBUG3 (("Adding pivot col to pivrow [IN] pattern\n")) ; if (rdeg [IN] >= max_rdeg) { /* :: pattern change (in) :: */ return (UMFPACK_ERROR_different_pattern) ; } Wrp [pivcol] = Wrpflag ; W_i [rdeg [IN]++] = pivcol ; } tpi = Row_tuples [pivrow [IN]] ; if (tpi) { tp = (Tuple *) (Memory + tpi) ; tp1 = tp ; tp2 = tp ; tpend = tp + Row_tlen [pivrow [IN]] ; for ( ; tp < tpend ; tp++) { e = tp->e ; ASSERT (e > 0 && e <= Work->nel) ; if (!E [e]) { continue ; /* element already deallocated */ } f = tp->f ; p = Memory + E [e] ; ep = (Element *) p ; p += UNITS (Element, 1) ; Cols = (Int *) p ; ncols = ep->ncols ; Rows = Cols + ncols ; if (Rows [f] == EMPTY) { continue ; /* row already assembled */ } ASSERT (pivrow [IN] == Rows [f]) ; for (j = 0 ; j < ncols ; j++) { col = Cols [j] ; ASSERT (col >= EMPTY && col < Work->n_col) ; if ((col >= 0) && (Wrp [col] != Wrpflag) && Fcpos [col] <0) { ASSERT (NON_PIVOTAL_COL (col)) ; if (rdeg [IN] >= max_rdeg) { /* :: pattern change (rdeg in failure) :: */ DEBUGm4 (("rdeg [IN] >= max_rdeg failure\n")) ; return (UMFPACK_ERROR_different_pattern) ; } Wrp [col] = Wrpflag ; W_i [rdeg [IN]++] = col ; } } *tp2++ = *tp ; /* leave the tuple in the list */ } Row_tlen [pivrow [IN]] = tp2 - tp1 ; } #ifndef NDEBUG DEBUG4 (("Reduced IN row:\n")) ; for (j = 0 ; j < fncols ; j++) { DEBUG6 ((" "ID" "ID" "ID"\n", j, Work->Fcols [j], Fcpos [Work->Fcols [j]])) ; ASSERT (Fcpos [Work->Fcols [j]] >= 0) ; } for (j = fncols ; j < rdeg [IN] ; j++) { DEBUG6 ((" "ID" "ID" "ID"\n", j, W_i [j], Wrp [W_i [j]])); ASSERT (W_i [j] >= 0 && W_i [j] < Work->n_col) ; ASSERT (Wrp [W_i [j]] == Wrpflag) ; } /* mark the end of the pattern in case we scan it by mistake */ /* Note that this means W_i must be of size >= fncols_max + 1 */ W_i [rdeg [IN]] = EMPTY ; #endif /* rdeg [IN] is now the exact degree of the IN row */ /* clear Work->Wrp. */ Work->Wrpflag++ ; /* All Wrp [0..n_col] is now < Wrpflag */ } } #ifndef NDEBUG /* check Wrp */ if (UMF_debug > 0 || Work->n_col < 1000) { for (i = 0 ; i < Work->n_col ; i++) { ASSERT (Wrp [i] < Work->Wrpflag) ; } } #endif /* ---------------------------------------------------------------------- */ /* construct the candidate row not in the front, if any */ /* ---------------------------------------------------------------------- */ #ifndef NDEBUG DEBUG4 (("pivrow [OUT]: "ID"\n", pivrow [OUT])) ; UMF_dump_rowcol (0, Numeric, Work, pivrow [OUT], TRUE) ; #endif /* If this is a candidate row from the row merge set, force it to be */ /* scanned (ignore prior_pivrow [OUT]). */ if (pivrow [OUT] != EMPTY) { freebie [OUT] = (pivrow [OUT] == prior_pivrow [OUT]) && cdeg1 > 0 ; ASSERT (cdeg1 >= 0) ; if (!freebie [OUT]) { Wrpflag = Work->Wrpflag ; /* -------------------------------------------------------------- */ /* construct the pattern of the row */ /* -------------------------------------------------------------- */ rdeg [OUT] = 0 ; ASSERT (pivrow [OUT] >= 0 && pivrow [OUT] < Work->n_row) ; ASSERT (NON_PIVOTAL_ROW (pivrow [OUT])) ; /* add the pivot column itself */ ASSERT (Wrp [pivcol] != Wrpflag) ; DEBUG3 (("Adding pivot col to pivrow [OUT] pattern\n")) ; if (rdeg [OUT] >= max_rdeg) { /* :: pattern change (out) :: */ return (UMFPACK_ERROR_different_pattern) ; } Wrp [pivcol] = Wrpflag ; W_o [rdeg [OUT]++] = pivcol ; tpi = Row_tuples [pivrow [OUT]] ; if (tpi) { tp = (Tuple *) (Memory + tpi) ; tp1 = tp ; tp2 = tp ; tpend = tp + Row_tlen [pivrow [OUT]] ; for ( ; tp < tpend ; tp++) { e = tp->e ; ASSERT (e > 0 && e <= Work->nel) ; if (!E [e]) { continue ; /* element already deallocated */ } f = tp->f ; p = Memory + E [e] ; ep = (Element *) p ; p += UNITS (Element, 1) ; Cols = (Int *) p ; ncols = ep->ncols ; Rows = Cols + ncols ; if (Rows [f] == EMPTY) { continue ; /* row already assembled */ } ASSERT (pivrow [OUT] == Rows [f]) ; for (j = 0 ; j < ncols ; j++) { col = Cols [j] ; ASSERT (col >= EMPTY && col < Work->n_col) ; if ((col >= 0) && (Wrp [col] != Wrpflag)) { ASSERT (NON_PIVOTAL_COL (col)) ; if (rdeg [OUT] >= max_rdeg) { /* :: pattern change (rdeg out failure) :: */ DEBUGm4 (("rdeg [OUT] failure\n")) ; return (UMFPACK_ERROR_different_pattern) ; } Wrp [col] = Wrpflag ; W_o [rdeg [OUT]++] = col ; } } *tp2++ = *tp ; /* leave the tuple in the list */ } Row_tlen [pivrow [OUT]] = tp2 - tp1 ; } #ifndef NDEBUG DEBUG4 (("Reduced row OUT:\n")) ; for (j = 0 ; j < rdeg [OUT] ; j++) { DEBUG6 ((" "ID" "ID" "ID"\n", j, W_o [j], Wrp [W_o [j]])) ; ASSERT (W_o [j] >= 0 && W_o [j] < Work->n_col) ; ASSERT (Wrp [W_o [j]] == Wrpflag) ; } /* mark the end of the pattern in case we scan it by mistake */ /* Note that this means W_o must be of size >= fncols_max + 1 */ W_o [rdeg [OUT]] = EMPTY ; #endif /* rdeg [OUT] is now the exact degree of the row */ /* clear Work->Wrp. */ Work->Wrpflag++ ; /* All Wrp [0..n] is now < Wrpflag */ } } DEBUG5 (("Row_search end ] \n")) ; #ifndef NDEBUG /* check Wrp */ if (UMF_debug > 0 || Work->n_col < 1000) { for (i = 0 ; i < Work->n_col ; i++) { ASSERT (Wrp [i] < Work->Wrpflag) ; } } #endif return (UMFPACK_OK) ; }
PRIVATE void get_L ( Int Lp [ ], /* of size n_row+1 */ Int Lj [ ], /* of size lnz, where lnz = Lp [n_row] */ double Lx [ ], /* of size lnz */ #ifdef COMPLEX double Lz [ ], /* of size lnz */ #endif NumericType *Numeric, Int Pattern [ ], /* workspace of size n_row */ Int Wi [ ] /* workspace of size n_row */ ) { /* ---------------------------------------------------------------------- */ /* local variables */ /* ---------------------------------------------------------------------- */ Entry value ; Entry *xp, *Lval ; Int deg, *ip, j, row, n_row, n_col, n_inner, *Lpos, *Lilen, *Lip, p, llen, lnz2, lp, newLchain, k, pos, npiv, *Li, n1 ; #ifdef COMPLEX Int split = SPLIT (Lz) ; #endif /* ---------------------------------------------------------------------- */ /* get parameters */ /* ---------------------------------------------------------------------- */ DEBUG4 (("get_L start:\n")) ; n_row = Numeric->n_row ; n_col = Numeric->n_col ; n_inner = MIN (n_row, n_col) ; npiv = Numeric->npiv ; n1 = Numeric->n1 ; Lpos = Numeric->Lpos ; Lilen = Numeric->Lilen ; Lip = Numeric->Lip ; deg = 0 ; /* ---------------------------------------------------------------------- */ /* count the nonzeros in each row of L */ /* ---------------------------------------------------------------------- */ #pragma ivdep for (row = 0 ; row < n_inner ; row++) { /* include the diagonal entry in the row counts */ Wi [row] = 1 ; } #pragma ivdep for (row = n_inner ; row < n_row ; row++) { Wi [row] = 0 ; } /* singletons */ for (k = 0 ; k < n1 ; k++) { DEBUG4 (("Singleton k "ID"\n", k)) ; deg = Lilen [k] ; if (deg > 0) { lp = Lip [k] ; Li = (Int *) (Numeric->Memory + lp) ; lp += UNITS (Int, deg) ; Lval = (Entry *) (Numeric->Memory + lp) ; for (j = 0 ; j < deg ; j++) { row = Li [j] ; value = Lval [j] ; DEBUG4 ((" row "ID" k "ID" value", row, k)) ; EDEBUG4 (value) ; DEBUG4 (("\n")) ; if (IS_NONZERO (value)) { Wi [row]++ ; } } } } /* non-singletons */ for (k = n1 ; k < npiv ; k++) { /* ------------------------------------------------------------------ */ /* make column of L in Pattern [0..deg-1] */ /* ------------------------------------------------------------------ */ lp = Lip [k] ; newLchain = (lp < 0) ; if (newLchain) { lp = -lp ; deg = 0 ; DEBUG4 (("start of chain for column of L\n")) ; } /* remove pivot row */ pos = Lpos [k] ; if (pos != EMPTY) { DEBUG4 ((" k "ID" removing row "ID" at position "ID"\n", k, Pattern [pos], pos)) ; ASSERT (!newLchain) ; ASSERT (deg > 0) ; ASSERT (pos >= 0 && pos < deg) ; ASSERT (Pattern [pos] == k) ; Pattern [pos] = Pattern [--deg] ; } /* concatenate the pattern */ ip = (Int *) (Numeric->Memory + lp) ; llen = Lilen [k] ; for (j = 0 ; j < llen ; j++) { row = *ip++ ; DEBUG4 ((" row "ID" k "ID"\n", row, k)) ; ASSERT (row > k && row < n_row) ; Pattern [deg++] = row ; } xp = (Entry *) (Numeric->Memory + lp + UNITS (Int, llen)) ; for (j = 0 ; j < deg ; j++) { DEBUG4 ((" row "ID" k "ID" value", Pattern [j], k)) ; row = Pattern [j] ; value = *xp++ ; EDEBUG4 (value) ; DEBUG4 (("\n")) ; if (IS_NONZERO (value)) { Wi [row]++ ; } } } /* ---------------------------------------------------------------------- */ /* construct the final row form of L */ /* ---------------------------------------------------------------------- */ /* create the row pointers */ lnz2 = 0 ; for (row = 0 ; row < n_row ; row++) { Lp [row] = lnz2 ; lnz2 += Wi [row] ; Wi [row] = Lp [row] ; } Lp [n_row] = lnz2 ; ASSERT (Numeric->lnz + n_inner == lnz2) ; /* add entries from the rows of L (singletons) */ for (k = 0 ; k < n1 ; k++) { DEBUG4 (("Singleton k "ID"\n", k)) ; deg = Lilen [k] ; if (deg > 0) { lp = Lip [k] ; Li = (Int *) (Numeric->Memory + lp) ; lp += UNITS (Int, deg) ; Lval = (Entry *) (Numeric->Memory + lp) ; for (j = 0 ; j < deg ; j++) { row = Li [j] ; value = Lval [j] ; DEBUG4 ((" row "ID" k "ID" value", row, k)) ; EDEBUG4 (value) ; DEBUG4 (("\n")) ; if (IS_NONZERO (value)) { p = Wi [row]++ ; Lj [p] = k ; #ifdef COMPLEX if (split) { Lx [p] = REAL_COMPONENT (value) ; Lz [p] = IMAG_COMPONENT (value) ; } else { Lx [2*p ] = REAL_COMPONENT (value) ; Lx [2*p+1] = IMAG_COMPONENT (value) ; } #else Lx [p] = value ; #endif } } } } /* add entries from the rows of L (non-singletons) */ for (k = n1 ; k < npiv ; k++) { /* ------------------------------------------------------------------ */ /* make column of L in Pattern [0..deg-1] */ /* ------------------------------------------------------------------ */ lp = Lip [k] ; newLchain = (lp < 0) ; if (newLchain) { lp = -lp ; deg = 0 ; DEBUG4 (("start of chain for column of L\n")) ; } /* remove pivot row */ pos = Lpos [k] ; if (pos != EMPTY) { DEBUG4 ((" k "ID" removing row "ID" at position "ID"\n", k, Pattern [pos], pos)) ; ASSERT (!newLchain) ; ASSERT (deg > 0) ; ASSERT (pos >= 0 && pos < deg) ; ASSERT (Pattern [pos] == k) ; Pattern [pos] = Pattern [--deg] ; } /* concatenate the pattern */ ip = (Int *) (Numeric->Memory + lp) ; llen = Lilen [k] ; for (j = 0 ; j < llen ; j++) { row = *ip++ ; DEBUG4 ((" row "ID" k "ID"\n", row, k)) ; ASSERT (row > k) ; Pattern [deg++] = row ; } xp = (Entry *) (Numeric->Memory + lp + UNITS (Int, llen)) ; for (j = 0 ; j < deg ; j++) { DEBUG4 ((" row "ID" k "ID" value", Pattern [j], k)) ; row = Pattern [j] ; value = *xp++ ; EDEBUG4 (value) ; DEBUG4 (("\n")) ; if (IS_NONZERO (value)) { p = Wi [row]++ ; Lj [p] = k ; #ifdef COMPLEX if (split) { Lx [p] = REAL_COMPONENT (value) ; Lz [p] = IMAG_COMPONENT (value) ; } else { Lx [2*p ] = REAL_COMPONENT (value) ; Lx [2*p+1] = IMAG_COMPONENT (value) ; } #else Lx [p] = value ; #endif } } } /* add all of the diagonal entries (L is unit diagonal) */ for (row = 0 ; row < n_inner ; row++) { p = Wi [row]++ ; Lj [p] = row ; #ifdef COMPLEX if (split) { Lx [p] = 1. ; Lz [p] = 0. ; } else { Lx [2*p ] = 1. ; Lx [2*p+1] = 0. ; } #else Lx [p] = 1. ; #endif ASSERT (Wi [row] == Lp [row+1]) ; } #ifndef NDEBUG DEBUG6 (("L matrix (stored by rows):")) ; UMF_dump_col_matrix (Lx, #ifdef COMPLEX Lz, #endif Lj, Lp, n_inner, n_row, Numeric->lnz+n_inner) ; #endif DEBUG4 (("get_L done:\n")) ; }