示例#1
0
static int Find_expired_msgs (LB_struct *lb, 
			int n_rms, unsigned int onp, int *ind_first)
{
    unsigned int cr_num_ptr;
    int n_exps, cr_nmsgs, off_first;

    cr_num_ptr = lb->hd->num_pt;
    cr_nmsgs = GET_NMSG (cr_num_ptr);	/* current # msgs */

    if (n_rms != N_MSG_RM_COMPU) {
	n_exps = n_rms;
	off_first = cr_nmsgs;
    }
    else {				/* evaluate number of expired/to-
					   be_expired msgs */
	off_first = GET_NMSG (onp);		/* # msgs before expiring */
	n_exps = off_first - cr_nmsgs;		/* # expired msgs */
	if (off_first >= lb->maxn_msgs)		/* one more msg will expire 
						   when the new msg is added */
	    n_exps++;
    }

    /* find index of the first expired/to-be-expired message */
    if (n_exps > 0) {
	int ptr;

	ptr = GET_POINTER (cr_num_ptr);
	*ind_first = (ptr - off_first + lb->n_slots) % lb->n_slots;
					/* slot index of the first msg */
    }
    else				/* avoid any negative return */
	n_exps = 0;

    return (n_exps);
}
示例#2
0
static int Find_replace_msgpt (LB_struct *lb, LB_id_t *id)
{
    int msgpt, page;

    if (*id == LB_ANY) {
	static int ss_off = 0;			/* circular search offset */
	unsigned int num_ptr;
	int pt0, cnt, turn, nmsgs, ind;

	if (!(lb->hd->miscflags & LB_MSG_DELETED))
	    return (LB_FAILURE);

	num_ptr = lb->hd->num_pt;
	nmsgs = GET_NMSG (num_ptr);		/* msg number */
	pt0 = GET_POINTER(num_ptr) - nmsgs;	/* pointer to the first msg */
	if (pt0 < 0)
	    pt0 += lb->ptr_range;

	if (nmsgs < lb->maxn_msgs)
	    return (LB_FAILURE);
	cnt = 0;
	if (ss_off >= nmsgs)
	    ss_off = 0;
	ind = (pt0 + ss_off) % lb->n_slots;
	turn = nmsgs - ss_off;
	while (1) {				/* search for a 0 size msg */
	    unsigned int ucnt;
	    LB_msg_info_t *msginfo;

	    ucnt = lb->dir[ind].loc;
	    msginfo = (LB_msg_info_t *)lb->msginfo + DB_WORD_OFFSET (ind, ucnt);
	    if (msginfo->len < 0)		/* found */
		break;
	    cnt++;
	    if (cnt == turn)			/* back to the first msg */
		ind = pt0 % lb->n_slots;
	    if (cnt >= nmsgs) {			/* LB is full */
		ss_off = (ss_off + cnt) % nmsgs;
		return (LB_FAILURE);
	    }
	    ind = (ind + 1) % lb->n_slots;
	}
	ss_off = (ss_off + cnt) % nmsgs;
	msgpt = ind;
	*id = lb->dir[ind].id + LB_MSG_DB_ID_MASK + 1;
	if (*id > LB_MAX_ID)
	    *id = (lb->dir[ind].id) & LB_MSG_DB_ID_MASK;
	lb->dir[ind].id = *id;
    }
    else if (LB_Search_msg (lb, *id, &msgpt, &page) < 0) /* not found */
	return (LB_FAILURE);

    lb->prev_id = *id;
    if (lb->umid != NULL)
	*lb->umid = *id;

    return (msgpt);
}
Int KLU_valid_LU (Int n, Int flag_test_start_ptr, Int Xip [ ],
                   Int Xlen [ ],  Unit LU [ ])
{
    Int *Xi ;
    Entry *Xx ;
    Int j, p1, p2, i, p, len ;

    PRINTF (("\ncolumn oriented matrix, n = %d\n", n)) ;
    if (n <= 0)
    {
        PRINTF (("n must be >= 0: %d\n", n)) ;
        return (FALSE) ;
    }
    if (flag_test_start_ptr && Xip [0] != 0)
    {
        /* column pointers must start at Xip [0] = 0*/
        PRINTF (("column 0 pointer bad\n")) ;
        return (FALSE) ;
    }

    for (j = 0 ; j < n ; j++)
    {
        p1 = Xip [j] ;
        PRINTF (("\nColumn of factor: %d p1: %d ", j, p1)) ;
        if (j < n-1)
        {
            p2 = Xip [j+1] ;
            PRINTF (("p2: %d ", p2)) ;
            if (p1 > p2)
            {
                /* column pointers must be ascending */
                PRINTF (("column %d pointer bad\n", j)) ;
                return (FALSE) ;
            }
        }
        PRINTF (("\n")) ;
        GET_POINTER (LU, Xip, Xlen, Xi, Xx, j, len) ;
        for (p = 0 ; p < len ; p++)
        {
            i = Xi [p] ;
            PRINTF (("row: %d", i)) ;
            if (i < 0 || i >= n)
            {
                /* row index out of range */
                PRINTF (("index out of range, col %d row %d\n", j, i)) ;
                return (FALSE) ;
            }
            if (Xx != (Entry *) NULL)
            {
                PRINT_ENTRY (Xx [p]) ;
            }
            PRINTF (("\n")) ;
        }
    }

    return (TRUE) ;
}
static void lsolve_numeric
(
    /* input, not modified on output: */
    Int Pinv [ ],	/* Pinv [i] = k if i is kth pivot row, or EMPTY if row i
			 * is not yet pivotal.  */
    Unit *LU,		/* LU factors (pattern and values) */
    Int Stack [ ],	/* stack for dfs */
    Int Lip [ ],	/* size n, Lip [k] is position in LU of column k of L */
    Int top,		/* top of stack on input */
    Int n,		/* A is n-by-n */
    Int Llen [ ],	/* size n, Llen [k] = # nonzeros in column k of L */

    /* output, must be zero on input: */
    Entry X [ ]	/* size n, initially zero.  On output,
		 * X [Ui [up1..up-1]] and X [Li [lp1..lp-1]]
		 * contains the solution. */

)
{
    Entry xj ;
    Entry *Lx ;
    Int *Li ;
    Int p, s, j, jnew, len ;

    /* solve Lx=b */
    for (s = top ; s < n ; s++)
    {
	/* forward solve with column j of L */
 	j = Stack [s] ;
	jnew = Pinv [j] ;
	ASSERT (jnew >= 0) ;
	xj = X [j] ;
	GET_POINTER (LU, Lip, Llen, Li, Lx, jnew, len) ;
	ASSERT (Lip [jnew] <= Lip [jnew+1]) ;
	for (p = 0 ; p < len ; p++)
	{
	    /*X [Li [p]] -= Lx [p] * xj ; */
	    MULT_SUB (X [Li [p]], Lx [p], xj) ;
	}
    }
}
示例#5
0
文件: klu.c 项目: Ascronia/fieldtrip
void KLU_ltsolve
(
    /* inputs, not modified: */
    Int n,
    Int Lip [ ],
    Int Llen [ ],
    Unit LU [ ],
    Int nrhs,
#ifdef COMPLEX
    Int conj_solve,
#endif
    /* right-hand-side on input, solution to L'x=b on output */
    Entry X [ ]
)
{
    Entry x [4], lik ;
    Int *Li ;
    Entry *Lx ;
    Int k, p, len, i ;

    switch (nrhs)
    {

        case 1:

            for (k = n-1 ; k >= 0 ; k--)
            {
                GET_POINTER (LU, Lip, Llen, Li, Lx, k, len) ;
                x [0] = X [k] ;
                for (p = 0 ; p < len ; p++)
                {
#ifdef COMPLEX
                    if (conj_solve)
                    {
                        /* x [0] -= CONJ (Lx [p]) * X [Li [p]] ; */
                        MULT_SUB_CONJ (x [0], X [Li [p]], Lx [p]) ;
                    }
                    else
#endif
                    {
                        /*x [0] -= Lx [p] * X [Li [p]] ;*/
                        MULT_SUB (x [0], Lx [p], X [Li [p]]) ;
                    }
                }
                X [k] = x [0] ;
            }
            break ;

        case 2:

            for (k = n-1 ; k >= 0 ; k--)
            {
                x [0] = X [2*k    ] ;
                x [1] = X [2*k + 1] ;
                GET_POINTER (LU, Lip, Llen, Li, Lx, k, len) ;
                for (p = 0 ; p < len ; p++)
                {
                    i = Li [p] ;
#ifdef COMPLEX
                    if (conj_solve)
                    {
                        CONJ (lik, Lx [p]) ;
                    }
                    else
#endif
                    {
                        lik = Lx [p] ;
                    }
                    MULT_SUB (x [0], lik, X [2*i]) ;
                    MULT_SUB (x [1], lik, X [2*i + 1]) ;
                }
                X [2*k    ] = x [0] ;
                X [2*k + 1] = x [1] ;
            }
            break ;

        case 3:

            for (k = n-1 ; k >= 0 ; k--)
            {
                x [0] = X [3*k    ] ;
                x [1] = X [3*k + 1] ;
                x [2] = X [3*k + 2] ;
                GET_POINTER (LU, Lip, Llen, Li, Lx, k, len) ;
                for (p = 0 ; p < len ; p++)
                {
                    i = Li [p] ;
#ifdef COMPLEX
                    if (conj_solve)
                    {
                        CONJ (lik, Lx [p]) ;
                    }
                    else
#endif
                    {
                        lik = Lx [p] ;
                    }
                    MULT_SUB (x [0], lik, X [3*i]) ;
                    MULT_SUB (x [1], lik, X [3*i + 1]) ;
                    MULT_SUB (x [2], lik, X [3*i + 2]) ;
                }
                X [3*k    ] = x [0] ;
                X [3*k + 1] = x [1] ;
                X [3*k + 2] = x [2] ;
            }
            break ;

        case 4:

            for (k = n-1 ; k >= 0 ; k--)
            {
                x [0] = X [4*k    ] ;
                x [1] = X [4*k + 1] ;
                x [2] = X [4*k + 2] ;
                x [3] = X [4*k + 3] ;
                GET_POINTER (LU, Lip, Llen, Li, Lx, k, len) ;
                for (p = 0 ; p < len ; p++)
                {
                    i = Li [p] ;
#ifdef COMPLEX
                    if (conj_solve)
                    {
                        CONJ (lik, Lx [p]) ;
                    }
                    else
#endif
                    {
                        lik = Lx [p] ;
                    }
                    MULT_SUB (x [0], lik, X [4*i]) ;
                    MULT_SUB (x [1], lik, X [4*i + 1]) ;
                    MULT_SUB (x [2], lik, X [4*i + 2]) ;
                    MULT_SUB (x [3], lik, X [4*i + 3]) ;
                }
                X [4*k    ] = x [0] ;
                X [4*k + 1] = x [1] ;
                X [4*k + 2] = x [2] ;
                X [4*k + 3] = x [3] ;
            }
            break ;
    }
}
示例#6
0
文件: klu.c 项目: Ascronia/fieldtrip
void KLU_usolve
(
    /* inputs, not modified: */
    Int n,
    Int Uip [ ],
    Int Ulen [ ],
    Unit LU [ ],
    Entry Udiag [ ],
    Int nrhs,
    /* right-hand-side on input, solution to Ux=b on output */
    Entry X [ ]
)
{
    Entry x [4], uik, ukk ;
    Int *Ui ;
    Entry *Ux ;
    Int k, p, len, i ;

    switch (nrhs)
    {

        case 1:

            for (k = n-1 ; k >= 0 ; k--)
            {
                GET_POINTER (LU, Uip, Ulen, Ui, Ux, k, len) ;
                /* x [0] = X [k] / Udiag [k] ; */
                DIV (x [0], X [k], Udiag [k]) ;
                X [k] = x [0] ;
                for (p = 0 ; p < len ; p++)
                {
                    /* X [Ui [p]] -= Ux [p] * x [0] ; */
                    MULT_SUB (X [Ui [p]], Ux [p], x [0]) ;

                }
            }

            break ;

        case 2:

            for (k = n-1 ; k >= 0 ; k--)
            {
                GET_POINTER (LU, Uip, Ulen, Ui, Ux, k, len) ;
                ukk = Udiag [k] ;
                /* x [0] = X [2*k    ] / ukk ;
                x [1] = X [2*k + 1] / ukk ; */
                DIV (x [0], X [2*k], ukk) ;
                DIV (x [1], X [2*k + 1], ukk) ;

                X [2*k    ] = x [0] ;
                X [2*k + 1] = x [1] ;
                for (p = 0 ; p < len ; p++)
                {
                    i = Ui [p] ;
                    uik = Ux [p] ;
                    /* X [2*i    ] -= uik * x [0] ;
                    X [2*i + 1] -= uik * x [1] ; */
                    MULT_SUB (X [2*i], uik, x [0]) ;
                    MULT_SUB (X [2*i + 1], uik, x [1]) ;
                }
            }

            break ;

        case 3:

            for (k = n-1 ; k >= 0 ; k--)
            {
                GET_POINTER (LU, Uip, Ulen, Ui, Ux, k, len) ;
                ukk = Udiag [k] ;

                DIV (x [0], X [3*k], ukk) ;
                DIV (x [1], X [3*k + 1], ukk) ;
                DIV (x [2], X [3*k + 2], ukk) ;

                X [3*k    ] = x [0] ;
                X [3*k + 1] = x [1] ;
                X [3*k + 2] = x [2] ;
                for (p = 0 ; p < len ; p++)
                {
                    i = Ui [p] ;
                    uik = Ux [p] ;
                    MULT_SUB (X [3*i], uik, x [0]) ;
                    MULT_SUB (X [3*i + 1], uik, x [1]) ;
                    MULT_SUB (X [3*i + 2], uik, x [2]) ;
                }
            }

            break ;

        case 4:

            for (k = n-1 ; k >= 0 ; k--)
            {
                GET_POINTER (LU, Uip, Ulen, Ui, Ux, k, len) ;
                ukk = Udiag [k] ;

                DIV (x [0], X [4*k], ukk) ;
                DIV (x [1], X [4*k + 1], ukk) ;
                DIV (x [2], X [4*k + 2], ukk) ;
                DIV (x [3], X [4*k + 3], ukk) ;

                X [4*k    ] = x [0] ;
                X [4*k + 1] = x [1] ;
                X [4*k + 2] = x [2] ;
                X [4*k + 3] = x [3] ;
                for (p = 0 ; p < len ; p++)
                {
                    i = Ui [p] ;
                    uik = Ux [p] ;

                    MULT_SUB (X [4*i], uik, x [0]) ;
                    MULT_SUB (X [4*i + 1], uik, x [1]) ;
                    MULT_SUB (X [4*i + 2], uik, x [2]) ;
                    MULT_SUB (X [4*i + 3], uik, x [3]) ;
                }
            }

            break ;

    }
}
示例#7
0
文件: klu.c 项目: Ascronia/fieldtrip
void KLU_lsolve
(
    /* inputs, not modified: */
    Int n,
    Int Lip [ ],
    Int Llen [ ],
    Unit LU [ ],
    Int nrhs,
    /* right-hand-side on input, solution to Lx=b on output */
    Entry X [ ]
)
{
    Entry x [4], lik ;
    Int *Li ;
    Entry *Lx ;
    Int k, p, len, i ;

    switch (nrhs)
    {

        case 1:
            for (k = 0 ; k < n ; k++)
            {
                x [0] = X [k] ;
                GET_POINTER (LU, Lip, Llen, Li, Lx, k, len) ;
                /* unit diagonal of L is not stored*/
                for (p = 0 ; p < len ; p++)
                {
                    /* X [Li [p]] -= Lx [p] * x [0] ; */
                    MULT_SUB (X [Li [p]], Lx [p], x [0]) ;
                }
            }
            break ;

        case 2:

            for (k = 0 ; k < n ; k++)
            {
                x [0] = X [2*k    ] ;
                x [1] = X [2*k + 1] ;
                GET_POINTER (LU, Lip, Llen, Li, Lx, k, len) ;
                for (p = 0 ; p < len ; p++)
                {
                    i = Li [p] ;
                    lik = Lx [p] ;
                    MULT_SUB (X [2*i], lik, x [0]) ;
                    MULT_SUB (X [2*i + 1], lik, x [1]) ;
                }
            }
            break ;

        case 3:

            for (k = 0 ; k < n ; k++)
            {
                x [0] = X [3*k    ] ;
                x [1] = X [3*k + 1] ;
                x [2] = X [3*k + 2] ;
                GET_POINTER (LU, Lip, Llen, Li, Lx, k, len) ;
                for (p = 0 ; p < len ; p++)
                {
                    i = Li [p] ;
                    lik = Lx [p] ;
                    MULT_SUB (X [3*i], lik, x [0]) ;
                    MULT_SUB (X [3*i + 1], lik, x [1]) ;
                    MULT_SUB (X [3*i + 2], lik, x [2]) ;
                }
            }
            break ;

        case 4:

            for (k = 0 ; k < n ; k++)
            {
                x [0] = X [4*k    ] ;
                x [1] = X [4*k + 1] ;
                x [2] = X [4*k + 2] ;
                x [3] = X [4*k + 3] ;
                GET_POINTER (LU, Lip, Llen, Li, Lx, k, len) ;
                for (p = 0 ; p < len ; p++)
                {
                    i = Li [p] ;
                    lik = Lx [p] ;
                    MULT_SUB (X [4*i], lik, x [0]) ;
                    MULT_SUB (X [4*i + 1], lik, x [1]) ;
                    MULT_SUB (X [4*i + 2], lik, x [2]) ;
                    MULT_SUB (X [4*i + 3], lik, x [3]) ;
                }
            }
            break ;

    }
}
示例#8
0
/*
 * GetClipboardSavebuf - gets data from the clipboard, and builds a
 *                       temporary savebuf from it
 */
int GetClipboardSavebuf( savebuf *clip )
{
    GLOBALHANDLE        hglob;
    char                _HUGE_ *ptr;
    char                _HUGE_ *cpos;
    fcb_list            fcblist;
    int                 i;
    bool                is_flushed;
    bool                has_lf;
    bool                record_done;
    char                ch;
    int                 used;

    if( !openClipboardForRead() ) {
        return( ERR_CLIPBOARD_EMPTY );
    }
    hglob = GetClipboardData( CF_TEXT );
    if( hglob == NULL ) {
        return( ERR_CLIPBOARD );
    }
    ptr = GetPtrGlobalLock( hglob );
    cpos = ptr;
    i = 0;
    is_flushed = false;
    has_lf = false;
    fcblist.head = NULL;
    fcblist.tail = NULL;
    record_done = false;

    /*
     * add all characters to ReadBuffer.  Each time this fills,
     * create a new FCB
     */
    while( (ch = *ptr) != '\0' ) {
        INC_POINTER( ptr );
        ReadBuffer[i++] = ch;
        if( ch == LF ) {
            has_lf = true;
        }
        if( i >= MAX_IO_BUFFER ) {
            is_flushed = true;
            used = addAnFcb( &fcblist, i );
            ptr = GET_POINTER( cpos, used );
            cpos = ptr;
            i = 0;
        }
    }

    /*
     * after we are done, see if any characters are left unprocessed
     */
    if( i != 0 ) {
        /*
         * check if this is a partial line
         */
        if( !is_flushed && !has_lf ) {
            clip->type = SAVEBUF_LINE;
            ReadBuffer[i] = 0;
            clip->u.data = MemAlloc( i + 1 );
            strcpy( clip->u.data, ReadBuffer );
            record_done = true;
        } else {
            // add LF to end of buffer
            if( i >= MAX_IO_BUFFER - 2 ) {
                addAnFcb( &fcblist, i );
                i = 0;
            }
            ReadBuffer[i++] = CR;
            ReadBuffer[i++] = LF;
            addAnFcb( &fcblist, i );
        }
    } else if( !is_flushed ) {
        clip->type = SAVEBUF_NOP;
        record_done = true;
    }

    if( !record_done ) {
        clip->type = SAVEBUF_FCBS;
        clip->u.fcbs.head = fcblist.head;
        clip->u.fcbs.tail = fcblist.tail;
    }

    GlobalUnlock( hglob );
    CloseClipboard();

    return( ERR_NO_ERR );

} /* GetClipboardSavebuf */
示例#9
0
文件: klu_extract.c 项目: GHilmarG/Ua
Int KLU_extract     /* returns TRUE if successful, FALSE otherwise */
(
    /* inputs: */
    KLU_numeric *Numeric,
    KLU_symbolic *Symbolic,

    /* outputs, all of which must be allocated on input */

    /* L */
    Int *Lp,        /* size n+1 */
    Int *Li,        /* size nnz(L) */
    double *Lx,     /* size nnz(L) */
#ifdef COMPLEX
    double *Lz,     /* size nnz(L) for the complex case, ignored if real */
#endif

    /* U */
    Int *Up,        /* size n+1 */
    Int *Ui,        /* size nnz(U) */
    double *Ux,     /* size nnz(U) */
#ifdef COMPLEX
    double *Uz,     /* size nnz(U) for the complex case, ignored if real */
#endif

    /* F */
    Int *Fp,        /* size n+1 */
    Int *Fi,        /* size nnz(F) */
    double *Fx,     /* size nnz(F) */
#ifdef COMPLEX
    double *Fz,     /* size nnz(F) for the complex case, ignored if real */
#endif

    /* P, row permutation */
    Int *P,         /* size n */

    /* Q, column permutation */
    Int *Q,         /* size n */

    /* Rs, scale factors */
    double *Rs,     /* size n */

    /* R, block boundaries */
    Int *R,         /* size nblocks+1 */

    KLU_common *Common
)
{
    Int *Lip, *Llen, *Uip, *Ulen, *Li2, *Ui2 ;
    Unit *LU ;
    Entry *Lx2, *Ux2, *Ukk ;
    Int i, k, block, nblocks, n, nz, k1, k2, nk, len, kk, p ;

    if (Common == NULL)
    {
        return (FALSE) ;
    }

    if (Symbolic == NULL || Numeric == NULL)
    {
        Common->status = KLU_INVALID ;
        return (FALSE) ;
    }

    Common->status = KLU_OK ;
    n = Symbolic->n ;
    nblocks = Symbolic->nblocks ;

    /* ---------------------------------------------------------------------- */
    /* extract scale factors */
    /* ---------------------------------------------------------------------- */

    if (Rs != NULL)
    {
        if (Numeric->Rs != NULL)
        {
            for (i = 0 ; i < n ; i++)
            {
                Rs [i] = Numeric->Rs [i] ;
            }
        }
        else
        {
            /* no scaling */
            for (i = 0 ; i < n ; i++)
            {
                Rs [i] = 1 ;
            }
        }
    }

    /* ---------------------------------------------------------------------- */
    /* extract block boundaries */
    /* ---------------------------------------------------------------------- */

    if (R != NULL)
    {
        for (block = 0 ; block <= nblocks ; block++)
        {
            R [block] = Symbolic->R [block] ;
        }
    }

    /* ---------------------------------------------------------------------- */
    /* extract final row permutation */
    /* ---------------------------------------------------------------------- */

    if (P != NULL)
    {
        for (k = 0 ; k < n ; k++)
        {
            P [k] = Numeric->Pnum [k] ;
        }
    }

    /* ---------------------------------------------------------------------- */
    /* extract column permutation */
    /* ---------------------------------------------------------------------- */

    if (Q != NULL)
    {
        for (k = 0 ; k < n ; k++)
        {
            Q [k] = Symbolic->Q [k] ;
        }
    }

    /* ---------------------------------------------------------------------- */
    /* extract each block of L */
    /* ---------------------------------------------------------------------- */

    if (Lp != NULL && Li != NULL && Lx != NULL
#ifdef COMPLEX
        && Lz != NULL
#endif
    )
    {
        nz = 0 ;
        for (block = 0 ; block < nblocks ; block++)
        {
            k1 = Symbolic->R [block] ;
            k2 = Symbolic->R [block+1] ;
            nk = k2 - k1 ;
            if (nk == 1)
            {
                /* singleton block */
                Lp [k1] = nz ;
                Li [nz] = k1 ;
                Lx [nz] = 1 ;
#ifdef COMPLEX
                Lz [nz] = 0 ;
#endif
                nz++ ;
            }
            else
            {
                /* non-singleton block */
                LU = Numeric->LUbx [block] ;
                Lip = Numeric->Lip + k1 ;
                Llen = Numeric->Llen + k1 ;
                for (kk = 0 ; kk < nk ; kk++)
                {
                    Lp [k1+kk] = nz ;
                    /* add the unit diagonal entry */
                    Li [nz] = k1 + kk ;
                    Lx [nz] = 1 ;
#ifdef COMPLEX
                    Lz [nz] = 0 ;
#endif
                    nz++ ;
                    GET_POINTER (LU, Lip, Llen, Li2, Lx2, kk, len) ;
                    for (p = 0 ; p < len ; p++)
                    {
                        Li [nz] = k1 + Li2 [p] ;
                        Lx [nz] = REAL (Lx2 [p]) ;
#ifdef COMPLEX
                        Lz [nz] = IMAG (Lx2 [p]) ;
#endif
                        nz++ ;
                    }
                }
            }
        }
        Lp [n] = nz ;
        ASSERT (nz == Numeric->lnz) ;
    }

    /* ---------------------------------------------------------------------- */
    /* extract each block of U */
    /* ---------------------------------------------------------------------- */

    if (Up != NULL && Ui != NULL && Ux != NULL
#ifdef COMPLEX
        && Uz != NULL
#endif
    )
    {
        nz = 0 ;
        for (block = 0 ; block < nblocks ; block++)
        {
            k1 = Symbolic->R [block] ;
            k2 = Symbolic->R [block+1] ;
            nk = k2 - k1 ;
            Ukk = ((Entry *) Numeric->Udiag) + k1 ;
            if (nk == 1)
            {
                /* singleton block */
                Up [k1] = nz ;
                Ui [nz] = k1 ;
                Ux [nz] = REAL (Ukk [0]) ;
#ifdef COMPLEX
                Uz [nz] = IMAG (Ukk [0]) ;
#endif
                nz++ ;
            }
            else
            {
                /* non-singleton block */
                LU = Numeric->LUbx [block] ;
                Uip = Numeric->Uip + k1 ;
                Ulen = Numeric->Ulen + k1 ;
                for (kk = 0 ; kk < nk ; kk++)
                {
                    Up [k1+kk] = nz ;
                    GET_POINTER (LU, Uip, Ulen, Ui2, Ux2, kk, len) ;
                    for (p = 0 ; p < len ; p++)
                    {
                        Ui [nz] = k1 + Ui2 [p] ;
                        Ux [nz] = REAL (Ux2 [p]) ;
#ifdef COMPLEX
                        Uz [nz] = IMAG (Ux2 [p]) ;
#endif
                        nz++ ;
                    }
                    /* add the diagonal entry */
                    Ui [nz] = k1 + kk ;
                    Ux [nz] = REAL (Ukk [kk]) ;
#ifdef COMPLEX
                    Uz [nz] = IMAG (Ukk [kk]) ;
#endif
                    nz++ ;
                }
            }
        }
        Up [n] = nz ;
        ASSERT (nz == Numeric->unz) ;
    }

    /* ---------------------------------------------------------------------- */
    /* extract the off-diagonal blocks, F */
    /* ---------------------------------------------------------------------- */

    if (Fp != NULL && Fi != NULL && Fx != NULL
#ifdef COMPLEX
        && Fz != NULL
#endif
    )
    {
        for (k = 0 ; k <= n ; k++)
        {
            Fp [k] = Numeric->Offp [k] ;
        }
        nz = Fp [n] ;
        for (k = 0 ; k < nz ; k++)
        {
            Fi [k] = Numeric->Offi [k] ;
        }
        for (k = 0 ; k < nz ; k++)
        {
            Fx [k] = REAL (((Entry *) Numeric->Offx) [k]) ;
#ifdef COMPLEX
            Fz [k] = IMAG (((Entry *) Numeric->Offx) [k]) ;
#endif
        }
    }

    return (TRUE) ;
}
示例#10
0
Int KLU_refactor        /* returns TRUE if successful, FALSE otherwise */
(
    /* inputs, not modified */
    Int Ap [ ],         /* size n+1, column pointers */
    Int Ai [ ],         /* size nz, row indices */
    double Ax [ ],
    KLU_symbolic<Entry, Int> *Symbolic,

    /* input/output */
    KLU_numeric<Entry, Int> *Numeric,
    KLU_common<Entry, Int>  *Common
)
{
    Entry ukk, ujk, s ;
    Entry *Offx, *Lx, *Ux, *X, *Az, *Udiag ;
    double *Rs ;
    Int *P, *Q, *R, *Pnum, *Offp, *Offi, *Ui, *Li, *Pinv, *Lip, *Uip, *Llen,
        *Ulen ;
    Unit **LUbx ;
    Unit *LU ;
    Int k1, k2, nk, k, block, oldcol, pend, oldrow, n, p, newrow, scale,
        nblocks, poff, i, j, up, ulen, llen, maxblock, nzoff ;

    /* ---------------------------------------------------------------------- */
    /* check inputs */
    /* ---------------------------------------------------------------------- */

    if (Common == NULL)
    {
        return (FALSE) ;
    }
    Common->status = KLU_OK ;

    if (Numeric == NULL)
    {
        /* invalid Numeric object */
        Common->status = KLU_INVALID ;
        return (FALSE) ;
    }

    Common->numerical_rank = EMPTY ;
    Common->singular_col = EMPTY ;

    Az = (Entry *) Ax ;

    /* ---------------------------------------------------------------------- */
    /* get the contents of the Symbolic object */
    /* ---------------------------------------------------------------------- */

    n = Symbolic->n ;
    P = Symbolic->P ;
    Q = Symbolic->Q ;
    R = Symbolic->R ;
    nblocks = Symbolic->nblocks ;
    maxblock = Symbolic->maxblock ;

    /* ---------------------------------------------------------------------- */
    /* get the contents of the Numeric object */
    /* ---------------------------------------------------------------------- */

    Pnum = Numeric->Pnum ;
    Offp = Numeric->Offp ;
    Offi = Numeric->Offi ;
    Offx = (Entry *) Numeric->Offx ;

    LUbx = (Unit **) Numeric->LUbx ;

    scale = Common->scale ;
    if (scale > 0)
    {
        /* factorization was not scaled, but refactorization is scaled */
        if (Numeric->Rs == NULL)
        {
            Numeric->Rs = (double *)KLU_malloc (n, sizeof (double), Common) ;
            if (Common->status < KLU_OK)
            {
                Common->status = KLU_OUT_OF_MEMORY ;
                return (FALSE) ;
            }
        }
    }
    else
    {
        /* no scaling for refactorization; ensure Numeric->Rs is freed.  This
         * does nothing if Numeric->Rs is already NULL. */
        Numeric->Rs = (double *) KLU_free (Numeric->Rs, n, sizeof (double), Common) ;
    }
    Rs = Numeric->Rs ;

    Pinv = Numeric->Pinv ;
    X = (Entry *) Numeric->Xwork ;
    Common->nrealloc = 0 ;
    Udiag = (Entry *) Numeric->Udiag ;
    nzoff = Symbolic->nzoff ;

    /* ---------------------------------------------------------------------- */
    /* check the input matrix compute the row scale factors, Rs */
    /* ---------------------------------------------------------------------- */

    /* do no scale, or check the input matrix, if scale < 0 */
    if (scale >= 0)
    {
        /* check for out-of-range indices, but do not check for duplicates */
        if (!KLU_scale (scale, n, Ap, Ai, Ax, Rs, NULL, Common))
        {
            return (FALSE) ;
        }
    }

    /* ---------------------------------------------------------------------- */
    /* clear workspace X */
    /* ---------------------------------------------------------------------- */

    for (k = 0 ; k < maxblock ; k++)
    {
        /* X [k] = 0 */
        CLEAR (X [k]) ;
    }

    poff = 0 ;

    /* ---------------------------------------------------------------------- */
    /* factor each block */
    /* ---------------------------------------------------------------------- */

    if (scale <= 0)
    {

        /* ------------------------------------------------------------------ */
        /* no scaling */
        /* ------------------------------------------------------------------ */

        for (block = 0 ; block < nblocks ; block++)
        {

            /* -------------------------------------------------------------- */
            /* the block is from rows/columns k1 to k2-1 */
            /* -------------------------------------------------------------- */

            k1 = R [block] ;
            k2 = R [block+1] ;
            nk = k2 - k1 ;

            if (nk == 1)
            {

                /* ---------------------------------------------------------- */
                /* singleton case */
                /* ---------------------------------------------------------- */

                oldcol = Q [k1] ;
                pend = Ap [oldcol+1] ;
                CLEAR (s) ;
                for (p = Ap [oldcol] ; p < pend ; p++)
                {
                    newrow = Pinv [Ai [p]] - k1 ;
                    if (newrow < 0 && poff < nzoff)
                    {
                        /* entry in off-diagonal block */
                        Offx [poff] = Az [p] ;
                        poff++ ;
                    }
                    else
                    {
                        /* singleton */
                        s = Az [p] ;
                    }
                }
                Udiag [k1] = s ;

            }
            else
            {

                /* ---------------------------------------------------------- */
                /* construct and factor the kth block */
                /* ---------------------------------------------------------- */

                Lip  = Numeric->Lip  + k1 ;
                Llen = Numeric->Llen + k1 ;
                Uip  = Numeric->Uip  + k1 ;
                Ulen = Numeric->Ulen + k1 ;
                LU = LUbx [block] ;

                for (k = 0 ; k < nk ; k++)
                {

                    /* ------------------------------------------------------ */
                    /* scatter kth column of the block into workspace X */
                    /* ------------------------------------------------------ */

                    oldcol = Q [k+k1] ;
                    pend = Ap [oldcol+1] ;
                    for (p = Ap [oldcol] ; p < pend ; p++)
                    {
                        newrow = Pinv [Ai [p]] - k1 ;
                        if (newrow < 0 && poff < nzoff)
                        {
                            /* entry in off-diagonal block */
                            Offx [poff] = Az [p] ;
                            poff++ ;
                        }
                        else
                        {
                            /* (newrow,k) is an entry in the block */
                            X [newrow] = Az [p] ;
                        }
                    }

                    /* ------------------------------------------------------ */
                    /* compute kth column of U, and update kth column of A */
                    /* ------------------------------------------------------ */

                    GET_POINTER (LU, Uip, Ulen, Ui, Ux, k, ulen) ;
                    for (up = 0 ; up < ulen ; up++)
                    {
                        j = Ui [up] ;
                        ujk = X [j] ;
                        /* X [j] = 0 */
                        CLEAR (X [j]) ;
                        Ux [up] = ujk ;
                        GET_POINTER (LU, Lip, Llen, Li, Lx, j, llen) ;
                        for (p = 0 ; p < llen ; p++)
                        {
                            /* X [Li [p]] -= Lx [p] * ujk */
                            MULT_SUB (X [Li [p]], Lx [p], ujk) ;
                        }
                    }
                    /* get the diagonal entry of U */
                    ukk = X [k] ;
                    /* X [k] = 0 */
                    CLEAR (X [k]) ;
                    /* singular case */
                    if (IS_ZERO (ukk))
                    {
                        /* matrix is numerically singular */
                        Common->status = KLU_SINGULAR ;
                        if (Common->numerical_rank == EMPTY)
                        {
                            Common->numerical_rank = k+k1 ;
                            Common->singular_col = Q [k+k1] ;
                        }
                        if (Common->halt_if_singular)
                        {
                            /* do not continue the factorization */
                            return (FALSE) ;
                        }
                    }
                    Udiag [k+k1] = ukk ;
                    /* gather and divide by pivot to get kth column of L */
                    GET_POINTER (LU, Lip, Llen, Li, Lx, k, llen) ;
                    for (p = 0 ; p < llen ; p++)
                    {
                        i = Li [p] ;
                        DIV (Lx [p], X [i], ukk) ;
                        CLEAR (X [i]) ;
                    }

                }
            }
        }

    }
    else
    {

        /* ------------------------------------------------------------------ */
        /* scaling */
        /* ------------------------------------------------------------------ */

        for (block = 0 ; block < nblocks ; block++)
        {

            /* -------------------------------------------------------------- */
            /* the block is from rows/columns k1 to k2-1 */
            /* -------------------------------------------------------------- */

            k1 = R [block] ;
            k2 = R [block+1] ;
            nk = k2 - k1 ;

            if (nk == 1)
            {

                /* ---------------------------------------------------------- */
                /* singleton case */
                /* ---------------------------------------------------------- */

                oldcol = Q [k1] ;
                pend = Ap [oldcol+1] ;
                CLEAR (s) ;
                for (p = Ap [oldcol] ; p < pend ; p++)
                {
                    oldrow = Ai [p] ;
                    newrow = Pinv [oldrow] - k1 ;
                    if (newrow < 0 && poff < nzoff)
                    {
                        /* entry in off-diagonal block */
                        /* Offx [poff] = Az [p] / Rs [oldrow] */
                        SCALE_DIV_ASSIGN (Offx [poff], Az [p], Rs [oldrow]) ;
                        poff++ ;
                    }
                    else
                    {
                        /* singleton */
                        /* s = Az [p] / Rs [oldrow] */
                        SCALE_DIV_ASSIGN (s, Az [p], Rs [oldrow]) ;
                    }
                }
                Udiag [k1] = s ;

            }
            else
            {

                /* ---------------------------------------------------------- */
                /* construct and factor the kth block */
                /* ---------------------------------------------------------- */

                Lip  = Numeric->Lip  + k1 ;
                Llen = Numeric->Llen + k1 ;
                Uip  = Numeric->Uip  + k1 ;
                Ulen = Numeric->Ulen + k1 ;
                LU = LUbx [block] ;

                for (k = 0 ; k < nk ; k++)
                {

                    /* ------------------------------------------------------ */
                    /* scatter kth column of the block into workspace X */
                    /* ------------------------------------------------------ */

                    oldcol = Q [k+k1] ;
                    pend = Ap [oldcol+1] ;
                    for (p = Ap [oldcol] ; p < pend ; p++)
                    {
                        oldrow = Ai [p] ;
                        newrow = Pinv [oldrow] - k1 ;
                        if (newrow < 0 && poff < nzoff)
                        {
                            /* entry in off-diagonal part */
                            /* Offx [poff] = Az [p] / Rs [oldrow] */
                            SCALE_DIV_ASSIGN (Offx [poff], Az [p], Rs [oldrow]);
                            poff++ ;
                        }
                        else
                        {
                            /* (newrow,k) is an entry in the block */
                            /* X [newrow] = Az [p] / Rs [oldrow] */
                            SCALE_DIV_ASSIGN (X [newrow], Az [p], Rs [oldrow]) ;
                        }
                    }

                    /* ------------------------------------------------------ */
                    /* compute kth column of U, and update kth column of A */
                    /* ------------------------------------------------------ */

                    GET_POINTER (LU, Uip, Ulen, Ui, Ux, k, ulen) ;
                    for (up = 0 ; up < ulen ; up++)
                    {
                        j = Ui [up] ;
                        ujk = X [j] ;
                        /* X [j] = 0 */
                        CLEAR (X [j]) ;
                        Ux [up] = ujk ;
                        GET_POINTER (LU, Lip, Llen, Li, Lx, j, llen) ;
                        for (p = 0 ; p < llen ; p++)
                        {
                            /* X [Li [p]] -= Lx [p] * ujk */
                            MULT_SUB (X [Li [p]], Lx [p], ujk) ;
                        }
                    }
                    /* get the diagonal entry of U */
                    ukk = X [k] ;
                    /* X [k] = 0 */
                    CLEAR (X [k]) ;
                    /* singular case */
                    if (IS_ZERO (ukk))
                    {
                        /* matrix is numerically singular */
                        Common->status = KLU_SINGULAR ;
                        if (Common->numerical_rank == EMPTY)
                        {
                            Common->numerical_rank = k+k1 ;
                            Common->singular_col = Q [k+k1] ;
                        }
                        if (Common->halt_if_singular)
                        {
                            /* do not continue the factorization */
                            return (FALSE) ;
                        }
                    }
                    Udiag [k+k1] = ukk ;
                    /* gather and divide by pivot to get kth column of L */
                    GET_POINTER (LU, Lip, Llen, Li, Lx, k, llen) ;
                    for (p = 0 ; p < llen ; p++)
                    {
                        i = Li [p] ;
                        DIV (Lx [p], X [i], ukk) ;
                        CLEAR (X [i]) ;
                    }
                }
            }
        }
    }

    /* ---------------------------------------------------------------------- */
    /* permute scale factors Rs according to pivotal row order */
    /* ---------------------------------------------------------------------- */

    if (scale > 0)
    {
        for (k = 0 ; k < n ; k++)
        {
            /* TODO : Check. REAL(X[k]) Can be just X[k] */
            /* REAL (X [k]) = Rs [Pnum [k]] ; */
            X [k] = Rs [Pnum [k]] ;
        }
        for (k = 0 ; k < n ; k++)
        {
            Rs [k] = REAL (X [k]) ;
        }
    }

#ifndef NDEBUGKLU2
    ASSERT (Offp [n] == poff) ;
    ASSERT (Symbolic->nzoff == poff) ;
    PRINTF (("\n------------------- Off diagonal entries, new:\n")) ;
    ASSERT (KLU_valid (n, Offp, Offi, Offx)) ;
    if (Common->status == KLU_OK)
    {
        PRINTF (("\n ########### KLU_BTF_REFACTOR done, nblocks %d\n",nblocks));
        for (block = 0 ; block < nblocks ; block++)
        {
            k1 = R [block] ;
            k2 = R [block+1] ;
            nk = k2 - k1 ;
            PRINTF ((
                "\n================KLU_refactor output: k1 %d k2 %d nk %d\n",
                k1, k2, nk)) ;
            if (nk == 1)
            {
                PRINTF (("singleton  ")) ;
                PRINT_ENTRY (Udiag [k1]) ;
            }
            else
            {
                Lip = Numeric->Lip + k1 ;
                Llen = Numeric->Llen + k1 ;
                LU = (Unit *) Numeric->LUbx [block] ;
                PRINTF (("\n---- L block %d\n", block)) ;
                ASSERT (KLU_valid_LU (nk, TRUE, Lip, Llen, LU)) ;
                Uip = Numeric->Uip + k1 ;
                Ulen = Numeric->Ulen + k1 ;
                PRINTF (("\n---- U block %d\n", block)) ;
                ASSERT (KLU_valid_LU (nk, FALSE, Uip, Ulen, LU)) ;
            }
        }
    }
#endif

    return (TRUE) ;
}
示例#11
0
/* Prune the columns of L to reduce work in subsequent depth-first searches */
static void prune
(
    /* input/output: */
    Int Lpend [ ],	/* Lpend [j] marks symmetric pruning point for L(:,j) */

    /* input: */
    Int Pinv [ ],	/* Pinv [i] = k if row i is kth pivot row, or EMPTY if
			 * row i is not yet pivotal.  */
    Int k,		/* prune using column k of U */
    Int pivrow,		/* current pivot row */

    /* input/output: */
    Unit *LU,		/* LU factors (pattern and values) */

    /* input */
    Int Uip [ ],	/* size n, column pointers for U */
    Int Lip [ ],	/* size n, column pointers for L */
    Int Ulen [ ],	/* size n, column length of U */
    Int Llen [ ]	/* size n, column length of L */
)
{
    Entry x ;
    Entry *Lx, *Ux ;
    Int *Li, *Ui ;
    Int p, i, j, p2, phead, ptail, llen, ulen ;

    /* check to see if any column of L can be pruned */
    GET_POINTER (LU, Uip, Ulen, Ui, Ux, k, ulen) ;
    for (p = 0 ; p < ulen ; p++)
    {
	j = Ui [p] ;
	ASSERT (j < k) ;
	PRINTF (("%d is pruned: %d. Lpend[j] %d Lip[j+1] %d\n",
	    j, Lpend [j] != EMPTY, Lpend [j], Lip [j+1])) ;
	if (Lpend [j] == EMPTY)
	{
	    /* scan column j of L for the pivot row */
            GET_POINTER (LU, Lip, Llen, Li, Lx, j, llen) ;
	    for (p2 = 0 ; p2 < llen ; p2++)
	    {
		if (pivrow == Li [p2])
		{
		    /* found it!  This column can be pruned */
#ifndef NDEBUG
		    PRINTF (("==== PRUNE: col j %d of L\n", j)) ;
		    {
			Int p3 ;
			for (p3 = 0 ; p3 < Llen [j] ; p3++)
			{
			    PRINTF (("before: %i  pivotal: %d\n", Li [p3],
					Pinv [Li [p3]] >= 0)) ;
			}
		    }
#endif

		    /* partition column j of L.  The unit diagonal of L
		     * is not stored in the column of L. */
		    phead = 0 ;
		    ptail = Llen [j] ;
		    while (phead < ptail)
		    {
			i = Li [phead] ;
			if (Pinv [i] >= 0)
			{
			    /* leave at the head */
			    phead++ ;
			}
			else
			{
			    /* swap with the tail */
			    ptail-- ;
			    Li [phead] = Li [ptail] ;
			    Li [ptail] = i ;
			    x = Lx [phead] ;
			    Lx [phead] = Lx [ptail] ;
			    Lx [ptail] = x ;
			}
		    }

		    /* set Lpend to one past the last entry in the
		     * first part of the column of L.  Entries in
		     * Li [0 ... Lpend [j]-1] are the only part of
		     * column j of L that needs to be scanned in the DFS.
		     * Lpend [j] was EMPTY; setting it >= 0 also flags
		     * column j as pruned. */
		    Lpend [j] = ptail ;

#ifndef NDEBUG
		    {
			Int p3 ;
			for (p3 = 0 ; p3 < Llen [j] ; p3++)
			{
			    if (p3 == Lpend [j]) PRINTF (("----\n")) ;
			    PRINTF (("after: %i  pivotal: %d\n", Li [p3],
					Pinv [Li [p3]] >= 0)) ;
			}
		    }
#endif

		    break ;
		}
	    }
	}
    }
}
示例#12
0
static Int lpivot
(
    Int diagrow,
    Int *p_pivrow,
    Entry *p_pivot,
    double *p_abs_pivot,
    double tol,
    Entry X [ ],
    Unit *LU,		/* LU factors (pattern and values) */
    Int Lip [ ],
    Int Llen [ ],
    Int k,
    Int n,

    Int Pinv [ ],	/* Pinv [i] = k if row i is kth pivot row, or EMPTY if
			 * row i is not yet pivotal.  */

    Int *p_firstrow,
    TRILINOS_KLU_common *Common
)
{
    Entry x, pivot, *Lx ;
    double abs_pivot, xabs ;
    Int p, i, ppivrow, pdiag, pivrow, *Li, last_row_index, firstrow, len ;

    pivrow = EMPTY ;
    if (Llen [k] == 0)
    {
	/* matrix is structurally singular */
	if (Common->halt_if_singular)
	{
	    return (FALSE) ;
	}
	for (firstrow = *p_firstrow ; firstrow < n ; firstrow++)
	{
	    PRINTF (("check %d\n", firstrow)) ;
	    if (Pinv [firstrow] < 0)
	    {
		/* found the lowest-numbered non-pivotal row.  Pick it. */
		pivrow = firstrow ;
		PRINTF (("Got pivotal row: %d\n", pivrow)) ;
		break ;
	    }
	}
	ASSERT (pivrow >= 0 && pivrow < n) ;
	CLEAR (pivot) ;
	*p_pivrow = pivrow ;
	*p_pivot = pivot ;
	*p_abs_pivot = 0 ;
	*p_firstrow = firstrow ;
	return (FALSE) ;
    }

    pdiag = EMPTY ;
    ppivrow = EMPTY ;
    abs_pivot = EMPTY ;
    i = Llen [k] - 1 ;
    GET_POINTER (LU, Lip, Llen, Li, Lx, k, len) ;
    last_row_index = Li [i] ;

    /* decrement the length by 1 */
    Llen [k] = i ;
    GET_POINTER (LU, Lip, Llen, Li, Lx, k, len) ;

    /* look in Li [0 ..Llen [k] - 1 ] for a pivot row */
    for (p = 0 ; p < len ; p++)
    {
	/* gather the entry from X and store in L */
	i = Li [p] ;
	x = X [i] ;
	CLEAR (X [i]) ;

	Lx [p] = x ;
	/* xabs = ABS (x) ; */
	ABS (xabs, x) ;

	/* find the diagonal */
	if (i == diagrow)
	{
	    pdiag = p ;
	}

	/* find the partial-pivoting choice */
	if (xabs > abs_pivot)
	{
	    abs_pivot = xabs ;
	    ppivrow = p ;
	}
    }

    /* xabs = ABS (X [last_row_index]) ;*/
    ABS (xabs, X [last_row_index]) ;
    if (xabs > abs_pivot)
    {
        abs_pivot = xabs ;
        ppivrow = EMPTY ;
    }

    /* compare the diagonal with the largest entry */
    if (last_row_index == diagrow)
    {
	if (xabs >= tol * abs_pivot)
	{
    	    abs_pivot = xabs ;
            ppivrow = EMPTY ;
        }
    }
    else if (pdiag != EMPTY)
    {
	/* xabs = ABS (Lx [pdiag]) ;*/
	ABS (xabs, Lx [pdiag]) ;
	if (xabs >= tol * abs_pivot)
	{
	    /* the diagonal is large enough */
	    abs_pivot = xabs ;
	    ppivrow = pdiag ;
	}
    }

    if (ppivrow != EMPTY)
    {
        pivrow = Li [ppivrow] ;
        pivot  = Lx [ppivrow] ;
	/* overwrite the ppivrow values with last index values */
        Li [ppivrow] = last_row_index ;
        Lx [ppivrow] = X [last_row_index] ;
    }
    else
    {
        pivrow = last_row_index ;
        pivot = X [last_row_index] ;
    }
    CLEAR (X [last_row_index]) ;

    *p_pivrow = pivrow ;
    *p_pivot = pivot ;
    *p_abs_pivot = abs_pivot ;
    ASSERT (pivrow >= 0 && pivrow < n) ;

    if (IS_ZERO (pivot) && Common->halt_if_singular)
    {
	/* numerically singular case */
	return (FALSE) ;
    }

    /* divide L by the pivot value */
    for (p = 0 ; p < Llen [k] ; p++)
    {
	/* Lx [p] /= pivot ; */
	DIV (Lx [p], Lx [p], pivot) ;
    }

    return (TRUE) ;
}
int main(int argc, char* argv[])
{
	HANDLE hFile = INVALID_HANDLE_VALUE,
		   hMap  = NULL;
	PBYTE pBuffer = NULL, pOps = NULL;
	DWORD dwFileSize = 0,
		  dwSizeOfHeaders = 0,
		  dwSections = 0,
		  dwBaseAddress = 0,
		  dwImageSize = 0,
  	      dwExportRVA  = 0,
		  dwExportSize = 0,
		  dwExportRaw  = 0,
		  dwExports = 0;
	PDWORD pdwFunctions, pszFunctionNames;
	PWORD  pwOrdinals;
	PIMAGE_NT_HEADERS     NTHeader;
	PIMAGE_DOS_HEADER     DOSHeader;
	PIMAGE_SECTION_HEADER Sections;
	PIMAGE_EXPORT_DIRECTORY pExportDirectory;
	hFile = CreateFile
	(
		"c:\\windows\\system32\\ntdll.dll",
		GENERIC_READ,
		FILE_SHARE_READ | FILE_SHARE_DELETE,
		NULL,
		OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL,
		NULL
	);

	if( hFile == INVALID_HANDLE_VALUE )
	{
		fprintf( stderr, "Could not open file: %08X\n", GetLastError() );
		goto done;
	}
	dwFileSize = GetFileSize( hFile, NULL );
	hMap = CreateFileMapping( hFile, NULL, PAGE_READONLY, 0, 0, NULL );
	if( hMap == NULL )
	{
		fprintf( stderr, "Could not create memory map: %08X\n", GetLastError() );
		goto done;
	}

	pBuffer = (PBYTE)MapViewOfFile( hMap, FILE_MAP_READ, 0, 0, 0 );
	if( hMap == NULL )
	{
		fprintf( stderr, "Could not obtain memory map view: %08X\n", GetLastError() );
		goto done;
	}
	if( pBuffer[0] != 'M' || pBuffer[1] != 'Z' )
	{
		fprintf( stderr, "Unexpected file header.\n" );
		goto done;
	}
	// start reading PE headers
	DOSHeader = (PIMAGE_DOS_HEADER)pBuffer;
	NTHeader  = (PIMAGE_NT_HEADERS)( pBuffer + DOSHeader->e_lfanew );

	dwSizeOfHeaders = NTHeader->OptionalHeader.SizeOfHeaders;
	dwBaseAddress   = NTHeader->OptionalHeader.ImageBase;
	dwImageSize     = NTHeader->OptionalHeader.SizeOfImage;
	dwSections      = NTHeader->FileHeader.NumberOfSections;
	// get first section header
	Sections = (PIMAGE_SECTION_HEADER)
	(
		pBuffer +
		DOSHeader->e_lfanew +
		sizeof(IMAGE_NT_HEADERS)
	);
	// now parse the export directory
	dwExportRVA  = NTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
	dwExportSize = NTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
	dwExportRaw  = RawOffsetByRVA( Sections, dwSections, dwFileSize, dwExportRVA );

	if( !dwExportRVA || !dwExportSize || !dwExportRaw )
	{
		fprintf( stderr, "Unexpected export directory structure.\n" );
		goto done;
	}
	pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)( pBuffer + dwExportRaw );
	pdwFunctions     = (PDWORD)GET_POINTER( pExportDirectory->AddressOfFunctions );
	pwOrdinals       = (PWORD)GET_POINTER( pExportDirectory->AddressOfNameOrdinals );
	pszFunctionNames = (PDWORD)GET_POINTER( pExportDirectory->AddressOfNames );
	dwExports		 = pExportDirectory->NumberOfNames;
	
	printf("pExportDirectory->NumberOfNames=%d\n",pExportDirectory->NumberOfNames);
	printf( "SYSCALL   RVA       NAME\n" );
	printf( "-----------------------------------------------\n" );

	// loop each exported symbol by name
	for( DWORD i = 0; i < pExportDirectory->NumberOfNames; ++i )
	{
		DWORD dwNameRVA = pszFunctionNames[ i ],
			  dwApiRVA  = pdwFunctions[ pwOrdinals[ i ] ],
			  dwSyscall = 0,
			  dwApiRaw  = RawOffsetByRVA( Sections, dwSections, dwFileSize, dwApiRVA ),
			  dwNameRaw = RawOffsetByRVA( Sections, dwSections, dwFileSize, dwNameRVA );
		pOps = pBuffer + dwApiRaw;

		/*
		 * Check if the API entry begins with:
		 *
		 *	MOV  EAX, IMM32
		 *  XOR  ECX, ECX
		 *  LEA  EDX, [ESP+04h]
		 *  CALL FS:[C0h]
		 *
		 * Or
		 *
		 *	MOV  EAX, IMM32
		 *  MOV  ECX, IMM32
		 *  LEA  EDX, [ESP+04h]
		 *  CALL FS:[C0h]
		 */

		if( pOps[0] == 0xB8 &&									            // mov eax, imm32
			(
				(
					pOps[5] == 0x33 && pOps[6] == 0xC9 &&		            // xor ecx, ecx
					!memcmp( &pOps[7],  "\x8D\x54\x24\x04", 4 ) &&          // lea edx, [esp+04h]
					!memcmp( &pOps[11], "\x64\xFF\x15\xC0\x00\x00\x00", 7 ) // call fs:[C0h]
				)
			||
				(
					pOps[5] == 0xB9 &&								        // mov ecx, imm32
					!memcmp( &pOps[10], "\x8D\x54\x24\x04", 4 ) &&          // lea edx, [esp+04h]
					!memcmp( &pOps[13], "\x64\xFF\x15\xC0\x00\x00\x00", 7 ) // call fs:[C0h]
				)
			)
		)
		{
			/*
			 * Extract the IMM32 part, this is our syscall number.
			 */
			dwSyscall  = *(DWORD *)( pOps + 1 );
			printf( "%08X  %08X  %s\n", dwSyscall, dwBaseAddress + dwApiRVA, pBuffer + dwNameRaw );
		}
	}

done:
	if( hFile != INVALID_HANDLE_VALUE )
	{
		CloseHandle( hFile );
	}
	if( pBuffer != NULL )
	{
		UnmapViewOfFile( pBuffer );
	}
	if( hMap != NULL )
	{
		CloseHandle( hMap );
	}
	return 0;
}//end main()
示例#14
0
static int LB_write_internal (int lbd, const char *msg, int length, LB_id_t id)
{
    LB_struct *lb;
    unsigned int num_ptr, org_num_ptr;
    int ptr, nmsgs;
    int n_rm;
    LB_dir *dir;
    int loc, new_space;
    int ret, ind, tag;

    if ((length < 0 && msg != DELETE_FLAG) || (length > 0 && msg == NULL) ||
	(id > LB_MAX_ID && id != LB_ANY))	/* check arguments */
	return (LB_BAD_ARGUMENT);

    /* get the LB structure, lock and mmap the file */
    lb = LB_Get_lb_structure (lbd, &ret);
    if (lb == NULL) 
	return (ret);
    if ((ret = LB_lock_mmap (lb, WRITE_PERM, EXC_LOCK)) < 0)
	return (LB_Unlock_return (lb, ret));

    if (!(lb->flags & LB_WRITE))	/* check write flag */
	return (LB_Unlock_return (lb, LB_BAD_ACCESS));

    if ((lb->flags & LB_DIRECT) &&	/* check direct access lock */
	LB_direct_access_lock (lb, TEST_LOCK, 0) != 0)
	return (LB_Unlock_return (lb, LB_BAD_ACCESS));

    if (length <= 0 && !(lb->flags & LB_DB))
	return (LB_Unlock_return (lb, LB_BAD_ARGUMENT));

    if (msg == DELETE_FLAG && (lb->hd->miscflags & LB_ID_BY_USER))
	return (LB_Unlock_return (lb, LB_NOT_SUPPORTED));

    if (lb->active_test) {		/* test LB_ACTIVE_SV_LOCK_OFF lock */
	ret = LB_process_lock (TEST_LOCK, lb, EXC_LOCK, LB_ACTIVE_SV_LOCK_OFF);
	if (ret != LB_LOCKED)
	    return (LB_Unlock_return (lb, LB_NOT_ACTIVE));
    }

    if (C_and_w && Check_msg (lb, msg, length, id))
	return (LB_Unlock_return (lb, 0));

    org_num_ptr = lb->hd->num_pt;	/* save for evaluating # expired msgs */

    if (lb->utag != NULL)
	tag = *(lb->utag);
    else
	tag = 0;

    /* process message replacing */
    if (lb->flags & LB_DB) {
	ret = Replace_message (lb, id, length, msg, tag);
	if (ret != MSG_NOT_REPLACED)
	    return (LB_Unlock_return (lb, ret));
    }

    /* find the write pointer and the new dir slot */
    num_ptr = lb->hd->num_pt;
    ptr = GET_POINTER (num_ptr);
    ind = ptr % lb->n_slots;		/* new slot index */
    nmsgs = GET_NMSG (num_ptr) + 1;	/* msg number including the new */

    if (lb->flags & LB_DB) {
	if (id != LB_ANY && (lb->hd->miscflags & LB_MSG_DELETED))
	    return (LB_Unlock_return (lb, LB_NOT_SUPPORTED));
	if (nmsgs > lb->maxn_msgs)
	    return (LB_Unlock_return (lb, LB_FULL));
    }

    /* get free space */
    loc = new_space = 0;
    if (length > 0)
	loc = LB_sms_get_free_space (lb, length, &new_space);
    if (loc < 0)
	return (LB_Unlock_return (lb, loc));

    /* write the message */
    if (length > 0 &&
	(ret = Write_msg_body (lb, loc, length, msg, new_space)) < 0)
	return (LB_Unlock_return (lb, ret));

    /* update the dir slot and the msg info */
    dir = lb->dir + ind;
    if (lb->flags & LB_DB) {
	LB_msg_info_t *msginfo;
	dir->loc = 0;			/* for ucnt */
	msginfo = (LB_msg_info_t *)lb->msginfo + DB_WORD_OFFSET (ind, 0);
	msginfo->len = length;
	msginfo->loc = loc;
    }
    else if (lb->ma_size == 0) {
	LB_msg_info_seq_t *msginfo;
	dir->loc = loc;
	msginfo = (LB_msg_info_seq_t *)lb->msginfo + ind;
	msginfo->len = length;
    }
    else
	dir->loc = (loc + length) % lb->ma_size;
    {	/* find the previous id and check if the LB is of non-decreasing ID */
	LB_id_t prid;

	/* this works since the entire control area is initialized to 0 */
	if (nmsgs > 1) {	/* find previous id */
	    int ppt;		/* pointer to the previous slot */
	    ppt = ptr - 1;
	    if (ppt < 0)
		ppt = lb->ptr_range - 1;
	    prid = (lb->dir [ppt % lb->n_slots]).id;
	}
	else
	    prid = 0;
	if (id == LB_ANY)		/* new id */
	    id = (lb_t)((prid + 1) % (unsigned int)(LB_MAX_ID + 1));
	else
	    lb->hd->miscflags |= LB_ID_BY_USER;
	if (id < prid && nmsgs > 1)	/* The LB is not of non-decreasing ID */
	    lb->hd->non_dec_id &= 0xfe;
    }
    dir->id = id;

    /* write the tag for the new message */
    if (lb->hd->tag_size > 0)
	LB_write_tag (lb, ind, tag, 0);

    /* process nrs and update LB time */
    if (lb->off_nra > 0 &&
	(ret = LB_process_nr (lb, id, length, tag,
				N_MSG_RM_COMPU, org_num_ptr)) < 0)
	    return (LB_Unlock_return (lb, ret));
    lb->hd->lb_time = time (NULL);

    /* update num_ptr and page number */
    if (nmsgs > lb->maxn_msgs)
	n_rm = nmsgs - lb->maxn_msgs;	/* number of messages to remove */
    else
	n_rm = 0;
    LB_Update_pointer (lb, 1, n_rm);	/* we add one new message */

    if (((lb->flags & LB_DB) || lb->ma_size == 0) &&
	length > 0)			/* sets sms_ok flag */
	lb->hd->sms_ok = 1;

    if (nmsgs > lb->maxn_msgs && lb->ma_size == 0) {
	int ln, lc, p;

	p = ptr - nmsgs + 1 + lb->n_slots;
	ln = LB_Get_message_info (lb, p, &lc, NULL);
	LB_sms_free_space (lb, lc, ln);
    }

    if (lb->flags & LB_SHARE_STREAM) {
	int exppt = (GET_POINTER (lb->hd->num_pt) + lb->ptr_range -
			(lb->maxn_msgs + 1)) % lb->ptr_range;
	if (LB_Ptr_compare (lb, exppt, (int)lb->hd->ptr_read) > 0)
	    lb->hd->ptr_read = exppt;
    }		/* advance ptr_read to keep close to the available msgs */

    lb->prev_id = id;
    if (lb->umid != NULL)
	*lb->umid = id;
    if (length < 0)
	length = 0;
    return (LB_Unlock_return (lb, length));
}
示例#15
0
文件: klu.c 项目: Ascronia/fieldtrip
void KLU_utsolve
(
    /* inputs, not modified: */
    Int n,
    Int Uip [ ],
    Int Ulen [ ],
    Unit LU [ ],
    Entry Udiag [ ],
    Int nrhs,
#ifdef COMPLEX
    Int conj_solve,
#endif
    /* right-hand-side on input, solution to Ux=b on output */
    Entry X [ ]
)
{
    Entry x [4], uik, ukk ;
    Int k, p, len, i ;
    Int *Ui ;
    Entry *Ux ;

    switch (nrhs)
    {

        case 1:

            for (k = 0 ; k < n ; k++)
            {
                GET_POINTER (LU, Uip, Ulen, Ui, Ux, k, len) ;
                x [0] = X [k] ;
                for (p = 0 ; p < len ; p++)
                {
#ifdef COMPLEX
                    if (conj_solve)
                    {
                        /* x [0] -= CONJ (Ux [p]) * X [Ui [p]] ; */
                        MULT_SUB_CONJ (x [0], X [Ui [p]], Ux [p]) ;
                    }
                    else
#endif
                    {
                        /* x [0] -= Ux [p] * X [Ui [p]] ; */
                        MULT_SUB (x [0], Ux [p], X [Ui [p]]) ;
                    }
                }
#ifdef COMPLEX
                if (conj_solve)
                {
                    CONJ (ukk, Udiag [k]) ;
                }
                else
#endif
                {
                    ukk = Udiag [k] ;
                }
                DIV (X [k], x [0], ukk) ;
            }
            break ;

        case 2:

            for (k = 0 ; k < n ; k++)
            {
                GET_POINTER (LU, Uip, Ulen, Ui, Ux, k, len) ;
                x [0] = X [2*k    ] ;
                x [1] = X [2*k + 1] ;
                for (p = 0 ; p < len ; p++)
                {
                    i = Ui [p] ;
#ifdef COMPLEX
                    if (conj_solve)
                    {
                        CONJ (uik, Ux [p]) ;
                    }
                    else
#endif
                    {
                        uik = Ux [p] ;
                    }
                    MULT_SUB (x [0], uik, X [2*i]) ;
                    MULT_SUB (x [1], uik, X [2*i + 1]) ;
                }
#ifdef COMPLEX
                if (conj_solve)
                {
                    CONJ (ukk, Udiag [k]) ;
                }
                else
#endif
                {
                    ukk = Udiag [k] ;
                }
                DIV (X [2*k], x [0], ukk) ;
                DIV (X [2*k + 1], x [1], ukk) ;
            }
            break ;

        case 3:

            for (k = 0 ; k < n ; k++)
            {
                GET_POINTER (LU, Uip, Ulen, Ui, Ux, k, len) ;
                x [0] = X [3*k    ] ;
                x [1] = X [3*k + 1] ;
                x [2] = X [3*k + 2] ;
                for (p = 0 ; p < len ; p++)
                {
                    i = Ui [p] ;
#ifdef COMPLEX
                    if (conj_solve)
                    {
                        CONJ (uik, Ux [p]) ;
                    }
                    else
#endif
                    {
                        uik = Ux [p] ;
                    }
                    MULT_SUB (x [0], uik, X [3*i]) ;
                    MULT_SUB (x [1], uik, X [3*i + 1]) ;
                    MULT_SUB (x [2], uik, X [3*i + 2]) ;
                }
#ifdef COMPLEX
                if (conj_solve)
                {
                    CONJ (ukk, Udiag [k]) ;
                }
                else
#endif
                {
                    ukk = Udiag [k] ;
                }
                DIV (X [3*k], x [0], ukk) ;
                DIV (X [3*k + 1], x [1], ukk) ;
                DIV (X [3*k + 2], x [2], ukk) ;
            }
            break ;

        case 4:

            for (k = 0 ; k < n ; k++)
            {
                GET_POINTER (LU, Uip, Ulen, Ui, Ux, k, len) ;
                x [0] = X [4*k    ] ;
                x [1] = X [4*k + 1] ;
                x [2] = X [4*k + 2] ;
                x [3] = X [4*k + 3] ;
                for (p = 0 ; p < len ; p++)
                {
                    i = Ui [p] ;
#ifdef COMPLEX
                    if (conj_solve)
                    {
                        CONJ (uik, Ux [p]) ;
                    }
                    else
#endif
                    {
                        uik = Ux [p] ;
                    }
                    MULT_SUB (x [0], uik, X [4*i]) ;
                    MULT_SUB (x [1], uik, X [4*i + 1]) ;
                    MULT_SUB (x [2], uik, X [4*i + 2]) ;
                    MULT_SUB (x [3], uik, X [4*i + 3]) ;
                }
#ifdef COMPLEX
                if (conj_solve)
                {
                    CONJ (ukk, Udiag [k]) ;
                }
                else
#endif
                {
                    ukk = Udiag [k] ;
                }
                DIV (X [4*k], x [0], ukk) ;
                DIV (X [4*k + 1], x [1], ukk) ;
                DIV (X [4*k + 2], x [2], ukk) ;
                DIV (X [4*k + 3], x [3], ukk) ;
            }
            break ;
    }
}
示例#16
0
size_t TRILINOS_KLU_kernel   /* final size of LU on output */
(
    /* input, not modified */
    Int n,	    /* A is n-by-n */
    Int Ap [ ],	    /* size n+1, column pointers for A */
    Int Ai [ ],	    /* size nz = Ap [n], row indices for A */
    Entry Ax [ ],   /* size nz, values of A */
    Int Q [ ],	    /* size n, optional input permutation */
    size_t lusize,  /* initial size of LU on input */

    /* output, not defined on input */
    Int Pinv [ ],   /* size n, inverse row permutation, where Pinv [i] = k if
		     * row i is the kth pivot row */
    Int P [ ],	    /* size n, row permutation, where P [k] = i if row i is the
		     * kth pivot row. */
    Unit **p_LU,	/* LU array, size lusize on input */
    Entry Udiag [ ],	/* size n, diagonal of U */
    Int Llen [ ],       /* size n, column length of L */
    Int Ulen [ ],	/* size n, column length of U */
    Int Lip [ ],	/* size n, column pointers for L */
    Int Uip [ ],	/* size n, column pointers for U */
    Int *lnz,		/* size of L*/
    Int *unz,		/* size of U*/
    /* workspace, not defined on input */
    Entry X [ ],    /* size n, undefined on input, zero on output */

    /* workspace, not defined on input or output */
    Int Stack [ ],  /* size n */
    Int Flag [ ],   /* size n */
    Int Ap_pos [ ],	/* size n */

    /* other workspace: */
    Int Lpend [ ],		    /* size n workspace, for pruning only */

    /* inputs, not modified on output */
    Int k1,	    	/* the block of A is from k1 to k2-1 */
    Int PSinv [ ],  	/* inverse of P from symbolic factorization */
    double Rs [ ],  	/* scale factors for A */

    /* inputs, modified on output */
    Int Offp [ ],   /* off-diagonal matrix (modified by this routine) */
    Int Offi [ ],
    Entry Offx [ ],
    /* --------------- */
    TRILINOS_KLU_common *Common
)
{
    Entry pivot ;
    double abs_pivot, xsize, nunits, tol, memgrow ;
    Entry *Ux ;
    Int *Li, *Ui ;
    Unit *LU ;		/* LU factors (pattern and values) */
    Int k, p, i, j, pivrow, kbar, diagrow, firstrow, lup, top, scale, len ;
    size_t newlusize ;

#ifndef NDEBUG
    Entry *Lx ;
#endif

    ASSERT (Common != NULL) ;
    scale = Common->scale ;
    tol = Common->tol ;
    memgrow = Common->memgrow ;
    *lnz = 0 ;
    *unz = 0 ;

    /* ---------------------------------------------------------------------- */
    /* get initial Li, Lx, Ui, and Ux */
    /* ---------------------------------------------------------------------- */

    PRINTF (("input: lusize %d \n", lusize)) ;
    ASSERT (lusize > 0) ;
    LU = *p_LU ;

    /* ---------------------------------------------------------------------- */
    /* initializations */
    /* ---------------------------------------------------------------------- */

    firstrow = 0 ;
    lup = 0 ;

    for (k = 0 ; k < n ; k++)
    {
	/* X [k] = 0 ; */
	CLEAR (X [k]) ;
	Flag [k] = EMPTY ;
	Lpend [k] = EMPTY ;	/* flag k as not pruned */
    }

    /* ---------------------------------------------------------------------- */
    /* mark all rows as non-pivotal and determine initial diagonal mapping */
    /* ---------------------------------------------------------------------- */

    /* PSinv does the symmetric permutation, so don't do it here */
    for (k = 0 ; k < n ; k++)
    {
	P [k] = k ;
	Pinv [k] = FLIP (k) ;	/* mark all rows as non-pivotal */
    }
    /* initialize the construction of the off-diagonal matrix */
    Offp [0] = 0 ;

    /* P [k] = row means that UNFLIP (Pinv [row]) = k, and visa versa.
     * If row is pivotal, then Pinv [row] >= 0.  A row is initially "flipped"
     * (Pinv [k] < EMPTY), and then marked "unflipped" when it becomes
     * pivotal. */

#ifndef NDEBUG
    for (k = 0 ; k < n ; k++)
    {
	PRINTF (("Initial P [%d] = %d\n", k, P [k])) ;
    }
#endif

    /* ---------------------------------------------------------------------- */
    /* factorize */
    /* ---------------------------------------------------------------------- */

    for (k = 0 ; k < n ; k++)
    {

	PRINTF (("\n\n==================================== k: %d\n", k)) ;

	/* ------------------------------------------------------------------ */
	/* determine if LU factors have grown too big */
	/* ------------------------------------------------------------------ */

	/* (n - k) entries for L and k entries for U */
	nunits = DUNITS (Int, n - k) + DUNITS (Int, k) +
		 DUNITS (Entry, n - k) + DUNITS (Entry, k) ;

        /* LU can grow by at most 'nunits' entries if the column is dense */
        PRINTF (("lup %d lusize %g lup+nunits: %g\n", lup, (double) lusize,
	    lup+nunits));
	xsize = ((double) lup) + nunits ;
	if (xsize > (double) lusize)
        {
            /* check here how much to grow */
	    xsize = (memgrow * ((double) lusize) + 4*n + 1) ;
            if (INT_OVERFLOW (xsize))
            {
                PRINTF (("Matrix is too large (Int overflow)\n")) ;
		Common->status = TRILINOS_KLU_TOO_LARGE ;
                return (lusize) ;
            }
            newlusize = memgrow * lusize + 2*n + 1 ;
	    /* Future work: retry mechanism in case of malloc failure */
	    LU = (Unit*) TRILINOS_KLU_realloc (newlusize, lusize, sizeof (Unit), LU, Common) ;
	    Common->nrealloc++ ;
            *p_LU = LU ;
            if (Common->status == TRILINOS_KLU_OUT_OF_MEMORY)
            {
                PRINTF (("Matrix is too large (LU)\n")) ;
                return (lusize) ;
            }
	    lusize = newlusize ;
            PRINTF (("inc LU to %d done\n", lusize)) ;
        }

	/* ------------------------------------------------------------------ */
	/* start the kth column of L and U */
	/* ------------------------------------------------------------------ */

	Lip [k] = lup ;

	/* ------------------------------------------------------------------ */
	/* compute the nonzero pattern of the kth column of L and U */
	/* ------------------------------------------------------------------ */

#ifndef NDEBUG
	for (i = 0 ; i < n ; i++)
	{
	    ASSERT (Flag [i] < k) ;
	    /* ASSERT (X [i] == 0) ; */
	    ASSERT (IS_ZERO (X [i])) ;
	}
#endif

	top = lsolve_symbolic (n, k, Ap, Ai, Q, Pinv, Stack, Flag,
		    Lpend, Ap_pos, LU, lup, Llen, Lip, k1, PSinv) ;

#ifndef NDEBUG
	PRINTF (("--- in U:\n")) ;
	for (p = top ; p < n ; p++)
	{
	    PRINTF (("pattern of X for U: %d : %d pivot row: %d\n",
		p, Stack [p], Pinv [Stack [p]])) ;
	    ASSERT (Flag [Stack [p]] == k) ;
	}
	PRINTF (("--- in L:\n")) ;
	Li = (Int *) (LU + Lip [k]);
	for (p = 0 ; p < Llen [k] ; p++)
	{
	    PRINTF (("pattern of X in L: %d : %d pivot row: %d\n",
		p, Li [p], Pinv [Li [p]])) ;
	    ASSERT (Flag [Li [p]] == k) ;
	}
	p = 0 ;
	for (i = 0 ; i < n ; i++)
	{
	    ASSERT (Flag [i] <= k) ;
	    if (Flag [i] == k) p++ ;
	}
#endif

	/* ------------------------------------------------------------------ */
	/* get the column of the matrix to factorize and scatter into X */
	/* ------------------------------------------------------------------ */

	construct_column (k, Ap, Ai, Ax, Q, X,
	    k1, PSinv, Rs, scale, Offp, Offi, Offx) ;

	/* ------------------------------------------------------------------ */
	/* compute the numerical values of the kth column (s = L \ A (:,k)) */
	/* ------------------------------------------------------------------ */

	lsolve_numeric (Pinv, LU, Stack, Lip, top, n, Llen, X) ;

#ifndef NDEBUG
	for (p = top ; p < n ; p++)
	{
	    PRINTF (("X for U %d : ",  Stack [p])) ;
	    PRINT_ENTRY (X [Stack [p]]) ;
	}
	Li = (Int *) (LU + Lip [k]) ;
	for (p = 0 ; p < Llen [k] ; p++)
	{
	    PRINTF (("X for L %d : ", Li [p])) ;
	    PRINT_ENTRY (X [Li [p]]) ;
	}
#endif

	/* ------------------------------------------------------------------ */
	/* partial pivoting with diagonal preference */
	/* ------------------------------------------------------------------ */

	/* determine what the "diagonal" is */
	diagrow = P [k] ;   /* might already be pivotal */
	PRINTF (("k %d, diagrow = %d, UNFLIP (diagrow) = %d\n",
	    k, diagrow, UNFLIP (diagrow))) ;

	/* find a pivot and scale the pivot column */
	if (!lpivot (diagrow, &pivrow, &pivot, &abs_pivot, tol, X, LU, Lip,
		    Llen, k, n, Pinv, &firstrow, Common))
	{
	    /* matrix is structurally or numerically singular */
	    Common->status = TRILINOS_KLU_SINGULAR ;
	    if (Common->numerical_rank == EMPTY)
	    {
		Common->numerical_rank = k+k1 ;
		Common->singular_col = Q [k+k1] ;
	    }
	    if (Common->halt_if_singular)
	    {
		/* do not continue the factorization */
		return (lusize) ;
	    }
	}

	/* we now have a valid pivot row, even if the column has NaN's or
	 * has no entries on or below the diagonal at all. */
	PRINTF (("\nk %d : Pivot row %d : ", k, pivrow)) ;
	PRINT_ENTRY (pivot) ;
	ASSERT (pivrow >= 0 && pivrow < n) ;
	ASSERT (Pinv [pivrow] < 0) ;

	/* set the Uip pointer */
	Uip [k] = Lip [k] + UNITS (Int, Llen [k]) + UNITS (Entry, Llen [k]) ;

        /* move the lup pointer to the position where indices of U
         * should be stored */
        lup += UNITS (Int, Llen [k]) + UNITS (Entry, Llen [k]) ;

        Ulen [k] = n - top ;

        /* extract Stack [top..n-1] to Ui and the values to Ux and clear X */
	GET_POINTER (LU, Uip, Ulen, Ui, Ux, k, len) ;
        for (p = top, i = 0 ; p < n ; p++, i++)
        {
	    j = Stack [p] ;
	    Ui [i] = Pinv [j] ;
	    Ux [i] = X [j] ;
	    CLEAR (X [j]) ;
        }

        /* position the lu index at the starting point for next column */
        lup += UNITS (Int, Ulen [k]) + UNITS (Entry, Ulen [k]) ;

	/* U(k,k) = pivot */
	Udiag [k] = pivot ;

	/* ------------------------------------------------------------------ */
	/* log the pivot permutation */
	/* ------------------------------------------------------------------ */

	ASSERT (UNFLIP (Pinv [diagrow]) < n) ;
	ASSERT (P [UNFLIP (Pinv [diagrow])] == diagrow) ;

	if (pivrow != diagrow)
	{
	    /* an off-diagonal pivot has been chosen */
	    Common->noffdiag++ ;
	    PRINTF ((">>>>>>>>>>>>>>>>> pivrow %d k %d off-diagonal\n",
			pivrow, k)) ;
	    if (Pinv [diagrow] < 0)
	    {
		/* the former diagonal row index, diagrow, has not yet been
		 * chosen as a pivot row.  Log this diagrow as the "diagonal"
		 * entry in the column kbar for which the chosen pivot row,
		 * pivrow, was originally logged as the "diagonal" */
		kbar = FLIP (Pinv [pivrow]) ;
		P [kbar] = diagrow ;
		Pinv [diagrow] = FLIP (kbar) ;
	    }
	}
	P [k] = pivrow ;
	Pinv [pivrow] = k ;

#ifndef NDEBUG
	for (i = 0 ; i < n ; i++) { ASSERT (IS_ZERO (X [i])) ;}
	GET_POINTER (LU, Uip, Ulen, Ui, Ux, k, len) ;
	for (p = 0 ; p < len ; p++)
	{
	    PRINTF (("Column %d of U: %d : ", k, Ui [p])) ;
	    PRINT_ENTRY (Ux [p]) ;
	}
	GET_POINTER (LU, Lip, Llen, Li, Lx, k, len) ;
	for (p = 0 ; p < len ; p++)
	{
	    PRINTF (("Column %d of L: %d : ", k, Li [p])) ;
	    PRINT_ENTRY (Lx [p]) ;
	}
#endif

	/* ------------------------------------------------------------------ */
	/* symmetric pruning */
	/* ------------------------------------------------------------------ */

	prune (Lpend, Pinv, k, pivrow, LU, Uip, Lip, Ulen, Llen) ;

	*lnz += Llen [k] + 1 ; /* 1 added to lnz for diagonal */
	*unz += Ulen [k] + 1 ; /* 1 added to unz for diagonal */
    }

    /* ---------------------------------------------------------------------- */
    /* finalize column pointers for L and U, and put L in the pivotal order */
    /* ---------------------------------------------------------------------- */

    for (p = 0 ; p < n ; p++)
    {
	Li = (Int *) (LU + Lip [p]) ;
	for (i = 0 ; i < Llen [p] ; i++)
	{
	    Li [i] = Pinv [Li [i]] ;
	}
    }

#ifndef NDEBUG
    for (i = 0 ; i < n ; i++)
    {
	PRINTF (("P [%d] = %d   Pinv [%d] = %d\n", i, P [i], i, Pinv [i])) ;
    }
    for (i = 0 ; i < n ; i++)
    {
	ASSERT (Pinv [i] >= 0 && Pinv [i] < n) ;
	ASSERT (P [i] >= 0 && P [i] < n) ;
	ASSERT (P [Pinv [i]] == i) ;
	ASSERT (IS_ZERO (X [i])) ;
    }
#endif

    /* ---------------------------------------------------------------------- */
    /* shrink the LU factors to just the required size */
    /* ---------------------------------------------------------------------- */

    newlusize = lup ;
    ASSERT ((size_t) newlusize <= lusize) ;

    /* this cannot fail, since the block is descreasing in size */
    LU = (Unit*) TRILINOS_KLU_realloc (newlusize, lusize, sizeof (Unit), LU, Common) ;
    *p_LU = LU ;
    return (newlusize) ;
}
示例#17
0
Int KLU_rgrowth         /* return TRUE if successful, FALSE otherwise */
(
    Int *Ap,
    Int *Ai,
    double *Ax,
    KLU_symbolic *Symbolic,
    KLU_numeric *Numeric,
    KLU_common *Common
)
{
    double temp, max_ai, max_ui, min_block_rgrowth ;
    Entry aik ;
    Int *Q, *Ui, *Uip, *Ulen, *Pinv ;
    Unit *LU ;
    Entry *Aentry, *Ux, *Ukk ;
    double *Rs ;
    Int i, newrow, oldrow, k1, k2, nk, j, oldcol, k, pend, len ;

    /* ---------------------------------------------------------------------- */
    /* check inputs */
    /* ---------------------------------------------------------------------- */

    if (Common == NULL)
    {
        return (FALSE) ;
    }

    if (Symbolic == NULL || Ap == NULL || Ai == NULL || Ax == NULL)
    {
        Common->status = KLU_INVALID ;
        return (FALSE) ;
    }

    if (Numeric == NULL)
    {
        /* treat this as a singular matrix */
        Common->rgrowth = 0 ;
        Common->status = KLU_SINGULAR ;
        return (TRUE) ;
    }
    Common->status = KLU_OK ;

    /* ---------------------------------------------------------------------- */
    /* compute the reciprocal pivot growth */
    /* ---------------------------------------------------------------------- */

    Aentry = (Entry *) Ax ;
    Pinv = Numeric->Pinv ;
    Rs = Numeric->Rs ;
    Q = Symbolic->Q ;
    Common->rgrowth = 1 ;

    for (i = 0 ; i < Symbolic->nblocks ; i++)
    {
        k1 = Symbolic->R[i] ;
        k2 = Symbolic->R[i+1] ;
        nk = k2 - k1 ;
        if (nk == 1)
        {
            continue ;      /* skip singleton blocks */
        }
        LU = (Unit *) Numeric->LUbx[i] ;
        Uip = Numeric->Uip + k1 ;
        Ulen = Numeric->Ulen + k1 ;
        Ukk = ((Entry *) Numeric->Udiag) + k1 ;
        min_block_rgrowth = 1 ;
        for (j = 0 ; j < nk ; j++)
        {
            max_ai = 0 ;
            max_ui = 0 ;
            oldcol = Q[j + k1] ;
            pend = Ap [oldcol + 1] ;
            for (k = Ap [oldcol] ; k < pend ; k++)
            {
                oldrow = Ai [k] ;
                newrow = Pinv [oldrow] ;
                if (newrow < k1)
                {
                    continue ;  /* skip entry outside the block */
                }
                ASSERT (newrow < k2) ;
                if (Rs != NULL)
                {
                    /* aik = Aentry [k] / Rs [oldrow] */
                    SCALE_DIV_ASSIGN (aik, Aentry [k], Rs [newrow]) ;
                }
                else
                {
                    aik = Aentry [k] ;
                }
                /* temp = ABS (aik) */
                ABS (temp, aik) ;
                if (temp > max_ai)
                {
                    max_ai = temp ;
                }
            }

            /* Ui is set but not used.  This is OK, because otherwise the macro
               would have to be redesigned. */
            GET_POINTER (LU, Uip, Ulen, Ui, Ux, j, len) ;
            for (k = 0 ; k < len ; k++)
            {
                /* temp = ABS (Ux [k]) */
                ABS (temp, Ux [k]) ;
                if (temp > max_ui)
                {
                    max_ui = temp ;
                }
            }
            /* consider the diagonal element */
            ABS (temp, Ukk [j]) ;
            if (temp > max_ui)
            {
                max_ui = temp ;
            }

            /* if max_ui is 0, skip the column */
            if (SCALAR_IS_ZERO (max_ui))
            {
                continue ;
            }
            temp = max_ai / max_ui ;
            if (temp < min_block_rgrowth)
            {
                min_block_rgrowth = temp ;
            }
        }

        if (min_block_rgrowth < Common->rgrowth)
        {
            Common->rgrowth = min_block_rgrowth ;
        }
    }
    return (TRUE) ;
}
示例#18
0
static void sort (Int n, Int *Xip, Int *Xlen, Unit *LU, Int *Tp, Int *Tj,
    Entry *Tx, Int *W)
{
    Int *Xi ;
    Entry *Xx ;
    Int p, i, j, len, nz, tp, xlen, pend ;

    ASSERT (KLU_valid_LU (n, FALSE, Xip, Xlen, LU)) ;

    /* count the number of entries in each row of L or U */ 
    for (i = 0 ; i < n ; i++)
    {
        W [i] = 0 ;
    }
    for (j = 0 ; j < n ; j++)
    {
        GET_POINTER (LU, Xip, Xlen, Xi, Xx, j, len) ;
        for (p = 0 ; p < len ; p++)
        {
            W [Xi [p]]++ ;
        }
    }

    /* construct the row pointers for T */
    nz = 0 ;
    for (i = 0 ; i < n ; i++)
    {
        Tp [i] = nz ;
        nz += W [i] ;
    }
    Tp [n] = nz ;
    for (i = 0 ; i < n ; i++)
    {
        W [i] = Tp [i] ;
    }

    /* transpose the matrix into Tp, Ti, Tx */
    for (j = 0 ; j < n ; j++)
    {
        GET_POINTER (LU, Xip, Xlen, Xi, Xx, j, len) ;
        for (p = 0 ; p < len ; p++)
        {
            tp = W [Xi [p]]++ ;
            Tj [tp] = j ;
            Tx [tp] = Xx [p] ;
        }
    }

    /* transpose the matrix back into Xip, Xlen, Xi, Xx */
    for (j = 0 ; j < n ; j++)
    {
        W [j] = 0 ;
    }
    for (i = 0 ; i < n ; i++)
    {
        pend = Tp [i+1] ;
        for (p = Tp [i] ; p < pend ; p++)
        {
            j = Tj [p] ;
            GET_POINTER (LU, Xip, Xlen, Xi, Xx, j, len) ;
            xlen = W [j]++ ;
            Xi [xlen] = i ;
            Xx [xlen] = Tx [p] ;
        }
    }

    ASSERT (KLU_valid_LU (n, FALSE, Xip, Xlen, LU)) ;
}